Teaching materials
\(~\)
‘hungry forager’ primer:
‘satiated forager’ primer:
Pigeon footage is available on the github page associated with this
report. It can be accessed here: https://github.com/tomkeaney/Biased_pigeons by
downloading the pigeon_video.mp4 file.
\(~\)
Load packages and the data
library(tidyverse) # tidy style coding
library(brms) # Bayesian models
library(loo) # for information criteria
library(tidybayes) # Bayesian aesthetics
library(MetBrewer) # colours
library(kableExtra) # tables
library(patchwork) # putting plots together
library(DT) # for search- and saveable tables
library(pander) # for simpler tables
library(png) # to load images
library(grid) # to plot images
library(ggdag) # to draw dags
data <- read_csv("data/pigeon_data.csv") %>%
mutate(Student_ID = as.factor(Student_ID),
Year = as.factor(Year),
Foraging_prop = (Foraging_percentage / 100)) %>%
filter(Year %in% c("2021", "2022", "2023"),
Foraging_percentage != "NA",
Primer_understood != "NA") %>%
filter(Student_ID != "60" & Student_ID != "68" & Student_ID != "70" & Student_ID != "72") %>% # remove students that completed the task multiple times
#Student_ID %in% c("60", "68", "70", "72")) %>%
select(-c(First_name, Surname, Peck_mean)) %>% # remove names when ready
left_join(
read_csv("data/gender_data.csv") %>%
mutate(Student_ID = as.factor(Student_ID))
) %>%
rename(Observer_ID = Student_ID) %>%
select(Observer_ID, Year, Gender, everything())
data_peck <-
data %>%
filter(Peck_rate_2 != "NA") %>%
pivot_longer(cols = Peck_rate_1:Peck_rate_2, names_to = "Trial",
values_to = "Peck_rate")
# Create a function to build HTML searchable tables
my_data_table <- function(df){
datatable(
df, rownames=FALSE,
autoHideNavigation = TRUE,
extensions = c("Scroller", "Buttons"),
options = list(
dom = 'Bfrtip',
deferRender=TRUE,
scrollX=TRUE, scrollY=400,
scrollCollapse=TRUE,
buttons =
list('pageLength', 'colvis', 'csv', list(
extend = 'pdf',
pageSize = 'A4',
orientation = 'landscape',
filename = 'full_dataset')),
pageLength = 78
)
)
}
my_data_table(data)
Column explanations
Observer_ID: unique, anonymised identifier for each
observer.
Year: year that the experiment was conducted.
Gender: upon enrollment at The University of
Melbourne, students are asked to indicate their title. We identified
women as observers that answered “Miss” or “Ms” and Men as those who
that answered “Mr”. Those with entirely missing entries were coded as
“NA”.
Bias_treatment: the primer the observer received,
where ‘satiated’ indicates that the observers were provided information
prior to a trial that suggested pigeons were fell fed, whereas ‘hungry’
indicated that the pigeons were in poor condition and hungry.
Expectation: we asked the observers to indicate
whether they thought the pigeons would be hungry or satiated. We
included this question to test whether observers were appropriately
primed by their bias treatment.
Primer_understood: did the observer’s expectation
match the primer they received?
Foraging_percentage: the percentage of pigeons that
observers estimated to be foraging over a 15 second period, while
observing a large flock.
Peck_rate_1: the number of times a single chosen
pigeon pecked the ground over a 15 second period.
Peck_rate_2: the number of times a second chosen
pigeon pecked the ground over a 15 second period.
Foraging_prop: proportion of pigeons estimated to be
foraging
\(~\)
Question 1: is estimation of foraging percentage affected by bias
manipulations?
\(~\)
Exploring allocation versus expectation
1
\(~\)
We find that 22 of the 78 observers indicated a
feeding motivation expectation opposite to that implied by the primer
they were allocated.
This suggests that Expectation may be a better predictor
of foraging estimation than allocated Bias_treatment. The
relationship between these and all other variables that we expect to
play a role in this system are depicted in Figure 1.
We explicitly assess the effect of treatment and expectation by
fitting two models:
a model with allocated primer (Bias_treatment) as
the predictor variable
a model with indicated hunger expectation
(Expectation) as the predictor variable
\(~\)
\(~\)
Model 1: allocated primer
# First let's model the effect of bias treatment on foraging estimation
foraging_model_treatment <- brm(Foraging_prop ~ 0 + Bias_treatment,
data = data, family = Beta,
prior = c(prior(normal(0, 1.5), class = b),
prior(exponential(1), class = phi)),
iter = 6000, warmup = 2000, chains = 4, cores = 4,
control = list(adapt_delta = 0.8, max_treedepth = 10),
seed = 1, file = "fits/foraging_model_treatment")
foraging_model_treatment <- add_criterion(foraging_model_treatment, criterion = "loo", file = "fits/foraging_model_treatment")
foraging_model_treatment
## Family: beta
## Links: mu = logit; phi = identity
## Formula: Foraging_prop ~ 0 + Bias_treatment
## Data: data (Number of observations: 78)
## Draws: 4 chains, each with iter = 6000; warmup = 2000; thin = 1;
## total post-warmup draws = 16000
##
## Population-Level Effects:
## Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
## Bias_treatmentHungry -0.47 0.14 -0.74 -0.20 1.00 14927
## Bias_treatmentSatiated -0.47 0.15 -0.76 -0.17 1.00 14749
## Tail_ESS
## Bias_treatmentHungry 12186
## Bias_treatmentSatiated 11819
##
## Family Specific Parameters:
## Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## phi 4.21 0.61 3.11 5.48 1.00 13695 12202
##
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).
foraging_model_treatment_gender <- brm(Foraging_prop ~ 0 + Gender * Bias_treatment,
data = data, family = Beta,
prior = c(prior(normal(0, 1.5), class = b),
prior(exponential(1), class = phi)),
iter = 6000, warmup = 2000, chains = 4, cores = 4,
control = list(adapt_delta = 0.8, max_treedepth = 10),
seed = 1, file = "fits/foraging_model_treatment_gender")
Table S1. Posterior estimates of the percentage of
pigeon feeding rate, split by the primer observers were allocated.
new_data <- tibble(Bias_treatment = c("Hungry", "Satiated"))
new_data %>%
left_join(data %>% group_by(Bias_treatment) %>% summarise(`n observers` = n())) %>%
cbind(fitted(foraging_model_treatment, newdata = new_data, summary = T) %>%
as_tibble() %>%
mutate(across(1:4, ~ .x *100),
across(1:4, round, 2))) %>%
rename("Estimated proportion foraging" = Estimate,
"Bias treatment" = Bias_treatment) %>%
pander(split.cell = 20, split.table = Inf)
| Hungry |
42 |
38.47 |
3.25 |
32.24 |
44.99 |
| Satiated |
36 |
38.59 |
3.51 |
31.85 |
45.65 |
Model 2: indicated expectation
# fit the same model, except using participant expectation rather than allocated bias treatment
foraging_model_expectation <- brm(Foraging_prop ~ 0 + Expectation,
data = data, family = Beta,
prior = c(prior(normal(0, 1.5), class = b),
prior(exponential(1), class = phi)),
iter = 6000, warmup = 2000, chains = 4, cores = 4,
control = list(adapt_delta = 0.8, max_treedepth = 10),
seed = 1, file = "fits/foraging_model_expectation")
foraging_model_expectation <- add_criterion(foraging_model_expectation, criterion = "loo", file = "fits/foraging_model_expectation")
foraging_model_expectation
## Family: beta
## Links: mu = logit; phi = identity
## Formula: Foraging_prop ~ 0 + Expectation
## Data: data (Number of observations: 78)
## Draws: 4 chains, each with iter = 6000; warmup = 2000; thin = 1;
## total post-warmup draws = 16000
##
## Population-Level Effects:
## Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## ExpectationHungry -0.40 0.13 -0.66 -0.14 1.00 15078 12139
## ExpectationSatiated -0.56 0.15 -0.87 -0.26 1.00 15944 12233
##
## Family Specific Parameters:
## Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## phi 4.25 0.62 3.12 5.55 1.00 16348 12206
##
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).
foraging_model_expectation_gender <- brm(Foraging_prop ~ 0 + Gender * Expectation,
data = data, family = Beta,
prior = c(prior(normal(0, 1.5), class = b),
prior(exponential(1), class = phi)),
iter = 6000, warmup = 2000, chains = 4, cores = 4,
control = list(adapt_delta = 0.8, max_treedepth = 10),
seed = 1, file = "fits/foraging_model_expectation_gender")
Table S2. Posterior estimates of the percentage of
pigeons foraging, split by the actual expectation of observers.
new_data_2 <- tibble(Expectation = c("Hungry", "Satiated"))
new_data_2 %>%
left_join(data %>% group_by(Expectation) %>% summarise(`n observers` = n())) %>%
cbind(fitted(foraging_model_expectation, newdata = new_data_2, summary = T) %>%
as_tibble() %>%
mutate(across(1:4, ~ .x *100),
across(1:4, round, 2))) %>%
rename("Estimated proportion foraging" = Estimate,
"Indicated expectation" = Expectation) %>%
pander(split.cell = 20, split.table = Inf)
| Hungry |
44 |
40.2 |
3.19 |
34.08 |
46.62 |
| Satiated |
34 |
36.38 |
3.56 |
29.61 |
43.56 |
\(~\)
Build Figure 1a-d
\(~\)
Get posterior means and difference contrasts
# treatment model
draws_treatment <-
as_draws_df(foraging_model_treatment) %>%
mutate(Hungry = inv_logit_scaled(b_Bias_treatmentHungry) *100,
Satiated = inv_logit_scaled(b_Bias_treatmentSatiated)*100,
diff_contrast = (Hungry - Satiated)) %>%
select(Hungry, Satiated, diff_contrast) %>%
pivot_longer(names_to = "Treatment", values_to = "Posterior_estimate", cols = 1:3) %>%
mutate(Predictor = "Allocated primer")
p2 <-
draws_treatment %>%
filter(Treatment != "diff_contrast") %>%
ggplot(aes(x = Treatment, y = Posterior_estimate)) +
stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
point_interval = "median_qi", point_fill = "white",
shape = 21, point_size = 4, stroke = 1.5) +
scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
coord_flip(ylim = c(25, 55)) +
#geom_vline(xintercept = 0, linetype = 2) +
#scale_y_continuous(breaks = c(, 0, 1)) +
xlab("Allocated primer") +
ylab("Estimated % pigeons foraging") +
theme_bw() +
theme(legend.position = "none",
panel.grid.minor = element_blank(),
text = element_text(size = 14))
p3 <-
draws_treatment %>%
filter(Treatment == "diff_contrast") %>%
ggplot(aes(y = Posterior_estimate)) +
stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
point_interval = "median_qi", point_fill = "white",
shape = 21, point_size = 4, stroke = 1.5, scale =0.5) +
scale_fill_manual(values = met.brewer("Hiroshige")[4]) +
coord_flip(ylim = c(-20, 20)) +
geom_hline(yintercept = 0, linetype = 2, linewidth = 0.75) +
#scale_y_continuous(breaks = c(, 0, 1)) +
xlab(NULL) +
ylab("Hungry - Satiated difference\ncontrast (% points)") +
theme_bw() +
theme(legend.position = "none",
panel.grid.minor = element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
text = element_text(size = 14))
# expectation model
draws_expectation <-
as_draws_df(foraging_model_expectation) %>%
mutate(Hungry = inv_logit_scaled(b_ExpectationHungry) *100,
Satiated = inv_logit_scaled(b_ExpectationSatiated)*100,
diff_contrast = (Hungry - Satiated)) %>%
select(Hungry, Satiated, diff_contrast) %>%
pivot_longer(names_to = "Treatment", values_to = "Posterior_estimate", cols = 1:3) %>%
mutate(Predictor = "Indicated expectation")
p4 <-
draws_expectation %>%
filter(Treatment != "diff_contrast") %>%
ggplot(aes(x = Treatment, y = Posterior_estimate)) +
stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
point_interval = "median_qi", point_fill = "white",
shape = 21, point_size = 4, stroke = 1.5) +
scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
coord_flip(ylim = c(25, 55)) +
#geom_vline(xintercept = 0, linetype = 2) +
#scale_y_continuous(breaks = c(, 0, 1)) +
xlab("Indicated expectation") +
ylab("Estimated % pigeons foraging") +
theme_bw() +
theme(legend.position = "none",
panel.grid.minor = element_blank(),
text = element_text(size = 14))
p5 <-
draws_expectation %>%
filter(Treatment == "diff_contrast") %>%
ggplot(aes(y = Posterior_estimate)) +
stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
point_interval = "median_qi", point_fill = "white",
shape = 21, point_size = 4, stroke = 1.5, scale =0.5) +
scale_fill_manual(values = met.brewer("Hiroshige")[4]) +
coord_flip(ylim = c(-20, 20)) +
geom_hline(yintercept = 0, linetype = 2, linewidth = 0.75) +
#scale_y_continuous(breaks = c(, 0, 1)) +
xlab(NULL) +
ylab("Hungry - Satiated difference\ncontrast (% points)") +
theme_bw() +
theme(legend.position = "none",
panel.grid.minor = element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
text = element_text(size = 14))
\(~\)
Question 2: is estimation of feeding rate affected by bias
manipulations?
\(~\)
We asked observers to count the number of pecks of the ground that a
selected pigeon made over a 1 minute period. We use the number of pecks
that occur as a measure of feeding rate.
We first estimated a baseline peck rate by observing 35 pigeons. To
select the pigeons we observed, we split a still image of the foraging
video (taken at time zero) into a 43 x 21 cell grid. From the 122 cells
that contained pigeons, 40 were chosen by random number generation (see
code chunk below). In the event that multiple pigeons were present in
the cell, we selected the most prominent to observe. Five observations
were discarded - three due to overlap of the same pigeon between cells
that were selected by the random number generator, and two more as the
pigeons left the field of view during the video and could no longer be
tracked.
# curly brackets run all lines included within them
{set.seed(1) # so that sample produces a reproducible sequence
sample(1:122, 40, replace = FALSE)}
## [1] 121 68 39 1 34 87 43 14 82 59 51 97 85 21 106 54 74 7 73
## [20] 79 110 37 89 101 118 100 44 103 33 84 35 70 108 42 38 20 28 117
## [39] 96 91
The selected pigeons for baseline observation are shown in the image
below
img <- readPNG("pigeon_selection.png")
grid.raster(img)

\(~\)
Estimating baseline feeding rate
\(~\)
Load in the data
baseline_data <- read_csv("data/baseline_peck_data.csv") %>%
select(1:5) %>% # remove the comments column
pivot_longer(cols = 4:5, names_to = "Observation", values_to = "Peck_rate") %>%
mutate(ID = as.factor(ID),
Observation = str_remove(Observation, "Peck_count_")) %>%
rename(Pigeon_ID = ID) %>%
filter(!is.na(Peck_rate))
my_data_table <- function(df){
datatable(
df, rownames=FALSE,
autoHideNavigation = TRUE,
extensions = c("Scroller", "Buttons"),
options = list(
dom = 'Bfrtip',
deferRender=TRUE,
scrollX=TRUE, scrollY=400,
scrollCollapse=TRUE,
buttons =
list('pageLength', 'colvis', 'csv', list(
extend = 'pdf',
pageSize = 'A4',
orientation = 'landscape',
filename = 'baseline_dataset')),
pageLength = 78
)
)
}
my_data_table(baseline_data)
X and Y represent grid
coordinates.
Pigeon_ID identifies a specific pigeon
Observation indicates whether this was the first or
second scoring for a single pigeon. We scored each pigeon twice as
distant pigeons were difficult to observe and to ensure that the correct
pigeon was tracked throughout the minute of observation.
Peck_rate is the number of times the ground was
pecked over a minute of observation.
\(~\)
Fit a simple model to estimate median peck rate
baseline_peck_model_zi <-
brm(Peck_rate ~ 1 + (1|Pigeon_ID),
family = zero_inflated_negbinomial(), data = baseline_data,
prior = c( prior(normal(0, 1.5), class = Intercept),
prior(exponential(1), class = sd),
prior(exponential(1), class = shape),
prior(exponential(1), class = zi)),
chains = 4, cores = 4, warmup = 2000, iter = 6000,
file = "fits/baseline_peck_model")
# wrangle the output
baseline_peck_predictions <-
baseline_peck_model_zi %>%
as_draws_df() %>%
mutate(Baseline_estimate = exp(b_Intercept),
peck_rate_sd = exp(sd_Pigeon_ID__Intercept)) %>%
select(Baseline_estimate, peck_rate_sd)
baseline_data %>%
distinct(Pigeon_ID) %>%
summarise(`n pigeons observed` = length(Pigeon_ID)) %>%
bind_cols(
fitted(baseline_peck_model_zi, summary = T, re_formula = NA) %>%
as_tibble() %>%
distinct(Estimate, .keep_all = T) %>%
mutate(across(1:4, round, 2)) %>%
rename(`Baseline median peck rate / per min` = Estimate)) %>%
pander()
\(~\)
Experimental data
\(~\)
Exploring allocation versus expectation
2.0
\(~\)
Once again, we expect that attention paid to and/or comprehension of
the primer statement has a large effect on observers’ perception of
pigeon foraging.
Lets again fit our two models:
a model with allocated primer (Bias_treatment) as
the predictor variable
a model with indicated hunger expectation
(Expectation) as the predictor variable
\(~\)
Model 1: allocated primer
# First let's model the effect of bias treatment on peck rate
peck_model_treatment <-
brm(Peck_rate ~ 0 + Bias_treatment + (1|Observer_ID),
data = data_peck, family = negbinomial,
prior = c(prior(normal(0, 1.5), class = b),
prior(exponential(1), class = sd)),
iter = 6000, warmup = 2000, chains = 4, cores = 4,
control = list(adapt_delta = 0.9, max_treedepth = 12),
seed = 1, file = "fits/peck_model_treatment")
peck_model_treatment <- add_criterion(peck_model_treatment, criterion = "loo", file = "fits/peck_model_treatment")
peck_model_treatment
## Family: negbinomial
## Links: mu = log; shape = identity
## Formula: Peck_rate ~ 0 + Bias_treatment + (1 | Observer_ID)
## Data: data_peck (Number of observations: 156)
## Draws: 4 chains, each with iter = 6000; warmup = 2000; thin = 1;
## total post-warmup draws = 16000
##
## Group-Level Effects:
## ~Observer_ID (Number of levels: 78)
## Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept) 0.21 0.15 0.01 0.54 1.00 4493 7497
##
## Population-Level Effects:
## Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS
## Bias_treatmentHungry 2.32 0.13 2.06 2.57 1.00 14993
## Bias_treatmentSatiated 2.16 0.14 1.89 2.44 1.00 19527
## Tail_ESS
## Bias_treatmentHungry 10405
## Bias_treatmentSatiated 11645
##
## Family Specific Parameters:
## Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## shape 0.91 0.13 0.69 1.18 1.00 13608 8978
##
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).
peck_model_treatment_gender <-
brm(Peck_rate ~ 0 + Gender * Bias_treatment + (1|Observer_ID),
data = data_peck, family = negbinomial,
prior = c(prior(normal(0, 1.5), class = b),
prior(exponential(1), class = sd)),
iter = 6000, warmup = 2000, chains = 4, cores = 4,
control = list(adapt_delta = 0.9, max_treedepth = 12),
seed = 1, file = "fits/peck_model_treatment_gender")
Table S3. The estimated peck rate of foraging
pigeons, split by the primer observers were allocated.
new_data %>%
bind_cols(fitted(peck_model_treatment, newdata = new_data, summary = T, re_formula = NA) %>%
as_tibble() %>%
mutate(across(1:4, round, 2))) %>%
left_join(data_peck %>% group_by(Bias_treatment) %>%
distinct(Observer_ID) %>% summarise(`n pigeons observed` = n())) %>%
rename("Estimated peck rate" = Estimate,
"Bias treatment" = Bias_treatment) %>%
bind_rows(fitted(baseline_peck_model_zi, summary = T, re_formula = NA) %>%
as_tibble() %>%
distinct(Estimate, .keep_all = T) %>%
mutate(across(1:4, round, 2)) %>%
rename("Estimated peck rate" = Estimate) %>%
mutate(`Bias treatment` = "Baseline") %>%
bind_cols(baseline_data %>%
distinct(Pigeon_ID) %>%
summarise(`n pigeons observed` = length(Pigeon_ID)))) %>%
select(`Bias treatment`, `n pigeons observed`, everything()) %>%
pander(split.cell = 20, split.table = Inf)
| Hungry |
42 |
10.23 |
1.34 |
7.83 |
13.12 |
| Satiated |
36 |
8.74 |
1.24 |
6.59 |
11.44 |
| Baseline |
35 |
1.32 |
0.51 |
0.54 |
2.53 |
Model 2: Indicated expectation
# fit the same model, except using participant expectation rather than allocated bias treatment
peck_model_expectation <- brm(Peck_rate ~ 0 + Expectation + (1|Observer_ID),
data = data_peck, family = negbinomial,
prior = c(prior(normal(0, 1.5), class = b),
prior(exponential(1), class = sd)),
iter = 6000, warmup = 2000, chains = 4, cores = 4,
control = list(adapt_delta = 0.95, max_treedepth = 12),
seed = 1, file = "fits/peck_model_expectation")
peck_model_expectation <- add_criterion(peck_model_expectation, criterion = "loo", file = "fits/peck_model_expectation")
peck_model_expectation
## Family: negbinomial
## Links: mu = log; shape = identity
## Formula: Peck_rate ~ 0 + Expectation + (1 | Observer_ID)
## Data: data_peck (Number of observations: 156)
## Draws: 4 chains, each with iter = 6000; warmup = 2000; thin = 1;
## total post-warmup draws = 16000
##
## Group-Level Effects:
## ~Observer_ID (Number of levels: 78)
## Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(Intercept) 0.18 0.13 0.01 0.48 1.00 4710 7228
##
## Population-Level Effects:
## Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## ExpectationHungry 2.41 0.12 2.18 2.66 1.00 16705 11820
## ExpectationSatiated 2.00 0.14 1.73 2.28 1.00 18644 12176
##
## Family Specific Parameters:
## Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
## shape 0.93 0.12 0.71 1.20 1.00 14884 11083
##
## Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).
#loo_compare(peck_model_treatment, peck_model_expectation)
peck_model_expectation_gender <- brm(Peck_rate ~ 0 + Gender * Expectation + (1|Observer_ID),
data = data_peck, family = negbinomial,
prior = c(prior(normal(0, 1.5), class = b),
prior(exponential(1), class = sd)),
iter = 6000, warmup = 2000, chains = 4, cores = 4,
control = list(adapt_delta = 0.95, max_treedepth = 12),
seed = 1, file = "fits/peck_model_expectation_gender")
Table S4. The estimated peck rate of foraging
pigeons, split by the indicated expectation of the observers.
new_data_2 %>%
bind_cols(fitted(peck_model_expectation, newdata = new_data_2, summary = T, re_formula = NA) %>%
as_tibble() %>%
mutate(across(1:4, round, 2))) %>%
left_join(data_peck %>% group_by(Expectation) %>%
distinct(Observer_ID) %>% summarise(`n pigeons observed` = n())) %>%
rename("Estimated peck rate" = Estimate,
"Indicated expectation" = Expectation) %>%
bind_rows(fitted(baseline_peck_model_zi, summary = T, re_formula = NA) %>%
as_tibble() %>%
distinct(Estimate, .keep_all = T) %>%
mutate(across(1:4, round, 2)) %>%
rename("Estimated peck rate" = Estimate) %>%
mutate(`Indicated expectation` = "Baseline") %>%
bind_cols(baseline_data %>%
distinct(Pigeon_ID) %>%
summarise(`n pigeons observed` = length(Pigeon_ID)))) %>%
select(`Indicated expectation`, `n pigeons observed`, everything()) %>%
pander(split.cell = 20, split.table = Inf)
| Hungry |
44 |
11.27 |
1.4 |
8.81 |
14.29 |
| Satiated |
34 |
7.46 |
1.06 |
5.62 |
9.81 |
| Baseline |
35 |
1.32 |
0.51 |
0.54 |
2.53 |
\(~\)
Build Figure 1e-h
\(~\)
Get posterior means and difference contrasts
# treatment model
peck_draws_treatment <-
as_draws_df(peck_model_treatment) %>%
mutate(Hungry = exp(b_Bias_treatmentHungry),
Satiated = exp(b_Bias_treatmentSatiated),
diff_contrast = (Hungry - Satiated)) %>%
select(Hungry, Satiated, diff_contrast) %>%
bind_cols(baseline_peck_predictions %>% select(Baseline_estimate)) %>%
pivot_longer(names_to = "Treatment", values_to = "Posterior_estimate", cols = 1:3) %>%
mutate(Predictor = "Allocated primer")
p6 <-
peck_draws_treatment %>%
filter(Treatment != "diff_contrast") %>%
ggplot(aes(x = Treatment, y = Posterior_estimate)) +
stat_slab(aes(y = Baseline_estimate),
linetype = 2, linewidth = 0.8, slab_fill = "white",
colour = "black") +
stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
point_interval = "median_qi", point_fill = "white",
shape = 21, point_size = 4, stroke = 1.5) +
scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
coord_flip(ylim = c(0, 20)) +
#geom_vline(xintercept = 0, linetype = 2) +
#scale_y_continuous(breaks = c(, 0, 1)) +
xlab("Allocated primer") +
ylab("Estimated pecks per min") +
theme_bw() +
theme(legend.position = "none",
panel.grid.minor = element_blank(),
text = element_text(size = 14))
p7 <-
peck_draws_treatment %>%
filter(Treatment == "diff_contrast") %>%
ggplot(aes(y = Posterior_estimate)) +
stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
point_interval = "median_qi", point_fill = "white",
shape = 21, point_size = 4, stroke = 1.5, scale =0.5) +
scale_fill_manual(values = met.brewer("Hiroshige")[4]) +
coord_flip(ylim = c(-5, 12)) +
geom_hline(yintercept = 0, linetype = 2, linewidth = 0.75) +
#scale_y_continuous(breaks = c(, 0, 1)) +
xlab(NULL) +
ylab("Hungry - Satiated difference\ncontrast (pecks per min)") +
theme_bw() +
theme(legend.position = "none",
panel.grid.minor = element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
text = element_text(size = 14))
# expectation model
peck_draws_expectation <-
as_draws_df(peck_model_expectation) %>%
mutate(Hungry = exp(b_ExpectationHungry),
Satiated = exp(b_ExpectationSatiated),
diff_contrast = (Hungry - Satiated)) %>%
select(Hungry, Satiated, diff_contrast) %>%
bind_cols(baseline_peck_predictions %>% select(Baseline_estimate)) %>%
pivot_longer(names_to = "Treatment", values_to = "Posterior_estimate", cols = 1:3) %>%
mutate(Predictor = "Allocated primer")
p8 <-
peck_draws_expectation %>%
filter(Treatment != "diff_contrast") %>%
ggplot(aes(x = Treatment, y = Posterior_estimate)) +
stat_slab(aes(y = Baseline_estimate),
linetype = 2, linewidth = 0.8, slab_fill = "white",
colour = "black") +
stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
point_interval = "median_qi", point_fill = "white",
shape = 21, point_size = 4, stroke = 1.5) +
scale_fill_manual(values = met.brewer("Hiroshige", 2)) +
coord_flip(ylim = c(0, 20)) +
#geom_vline(xintercept = 0, linetype = 2) +
#scale_y_continuous(breaks = c(, 0, 1)) +
xlab("Indicated expectation") +
ylab("Estimated pecks per min") +
theme_bw() +
theme(legend.position = "none",
panel.grid.minor = element_blank(),
text = element_text(size = 14))
p9 <-
peck_draws_expectation %>%
filter(Treatment == "diff_contrast") %>%
ggplot(aes(y = Posterior_estimate)) +
stat_halfeye(aes(fill = Treatment), .width = c(0.66, 0.95), alpha = 0.9,
point_interval = "median_qi", point_fill = "white",
shape = 21, point_size = 4, stroke = 1.5, scale =0.5) +
scale_fill_manual(values = met.brewer("Hiroshige")[4]) +
coord_flip(ylim = c(-5, 12)) +
geom_hline(yintercept = 0, linetype = 2, linewidth = 0.75) +
#scale_y_continuous(breaks = c(, 0, 1)) +
xlab(NULL) +
ylab("Hungry - Satiated difference\ncontrast (pecks per min)") +
theme_bw() +
theme(legend.position = "none",
panel.grid.minor = element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
text = element_text(size = 14))
\(~\)
Find the difference between baseline and observer estimates
Table S5. The degree to which each group of
observer’s overestimates feeding rate (number of ground pecks per
minute)
baseline_peck_predictions %>% select(Baseline_estimate) %>% bind_cols(
as_draws_df(peck_model_treatment) %>%
mutate(Hungry = exp(b_Bias_treatmentHungry),
Satiated = exp(b_Bias_treatmentSatiated)) %>%
select(Hungry, Satiated)) %>%
mutate(`Bias treatment Satiated / Baseline` = Satiated / Baseline_estimate,
`Bias treatment Hungry / Baseline` = Hungry / Baseline_estimate) %>%
select(contains("Bias")) %>%
pivot_longer(cols = everything(), values_to = "estimate", names_to = "Stat") %>%
group_by(Stat) %>%
summarise_draws("median", "sd", ~quantile(.x, probs = c(0.025, 0.975), na.rm = TRUE), .cores = 4) %>%
select(-variable) %>%
bind_rows(
baseline_peck_predictions %>% select(Baseline_estimate) %>% bind_cols(
as_draws_df(peck_model_expectation) %>%
mutate(Hungry = exp(b_ExpectationHungry),
Satiated = exp(b_ExpectationSatiated)) %>%
select(Hungry, Satiated)) %>%
mutate(`Expectation Satiated / Baseline` = Satiated / Baseline_estimate,
`Expectation Hungry / Baseline` = Hungry / Baseline_estimate) %>%
select(contains("Expectation")) %>%
pivot_longer(cols = everything(), values_to = "estimate", names_to = "Stat") %>%
group_by(Stat) %>%
summarise_draws("median", "sd", ~quantile(.x, probs = c(0.025, 0.975), na.rm = TRUE), .cores = 4) %>%
select(-variable)
) %>%
pander()
| Bias treatment Hungry / Baseline |
7.883 |
4.111 |
3.728 |
19.04 |
| Bias treatment Satiated / Baseline |
6.713 |
3.562 |
3.149 |
16.48 |
| Expectation Hungry / Baseline |
8.67 |
4.554 |
4.108 |
20.94 |
| Expectation Satiated / Baseline |
5.722 |
3.065 |
2.688 |
14 |
Session info
sessionInfo() %>% pander
R version 4.3.1 (2023-06-16 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale: LC_COLLATE=English_Australia.utf8,
LC_CTYPE=English_Australia.utf8,
LC_MONETARY=English_Australia.utf8, LC_NUMERIC=C and
LC_TIME=English_Australia.utf8
attached base packages: grid,
stats, graphics, grDevices, utils,
datasets, methods and base
other attached packages: ggdag(v.0.2.10),
png(v.0.1-8), pander(v.0.6.5), DT(v.0.28),
patchwork(v.1.1.2), kableExtra(v.1.3.4),
MetBrewer(v.0.2.0), tidybayes(v.3.0.4),
loo(v.2.6.0), brms(v.2.19.0), Rcpp(v.1.0.11),
lubridate(v.1.9.2), forcats(v.1.0.0),
stringr(v.1.5.0), dplyr(v.1.1.2),
purrr(v.1.0.1), readr(v.2.1.4),
tidyr(v.1.3.0), tibble(v.3.2.1),
ggplot2(v.3.4.2) and tidyverse(v.2.0.0)
loaded via a namespace (and not attached):
tensorA(v.0.36.2), rstudioapi(v.0.15.0),
jsonlite(v.1.8.7), magrittr(v.2.0.3),
farver(v.2.1.1), rmarkdown(v.2.23),
vctrs(v.0.6.3), base64enc(v.0.1-3),
webshot(v.0.5.5), htmltools(v.0.5.5),
dagitty(v.0.3-1), distributional(v.0.3.2),
curl(v.5.0.1), sass(v.0.4.7),
StanHeaders(v.2.26.27), bslib(v.0.5.0),
htmlwidgets(v.1.6.2), plyr(v.1.8.8),
zoo(v.1.8-12), cachem(v.1.0.8),
igraph(v.1.5.0.1), mime(v.0.12),
lifecycle(v.1.0.3), pkgconfig(v.2.0.3),
colourpicker(v.1.2.0), Matrix(v.1.5-4.1),
R6(v.2.5.1), fastmap(v.1.1.1),
shiny(v.1.7.4.1), digest(v.0.6.33),
colorspace(v.2.1-0), ps(v.1.7.5),
crosstalk(v.1.2.0), labeling(v.0.4.2),
fansi(v.1.0.4), timechange(v.0.2.0),
polyclip(v.1.10-4), httr(v.1.4.6),
abind(v.1.4-5), compiler(v.4.3.1),
bit64(v.4.0.5), withr(v.2.5.0),
backports(v.1.4.1), inline(v.0.3.19),
shinystan(v.2.6.0), viridis(v.0.6.4),
highr(v.0.10), pkgbuild(v.1.4.2),
ggforce(v.0.4.1), MASS(v.7.3-60),
gtools(v.3.9.4), tools(v.4.3.1),
httpuv(v.1.6.11), threejs(v.0.3.3),
glue(v.1.6.2), callr(v.3.7.3),
nlme(v.3.1-162), promises(v.1.2.0.1),
checkmate(v.2.2.0), reshape2(v.1.4.4),
generics(v.0.1.3), gtable(v.0.3.3),
tzdb(v.0.4.0), hms(v.1.1.3),
tidygraph(v.1.2.3), xml2(v.1.3.5),
utf8(v.1.2.3), ggrepel(v.0.9.3),
pillar(v.1.9.0), ggdist(v.3.3.0),
markdown(v.1.7), vroom(v.1.6.3),
posterior(v.1.4.1), later(v.1.3.1),
tweenr(v.2.0.2), lattice(v.0.21-8),
bit(v.4.0.5), tidyselect(v.1.2.0),
miniUI(v.0.1.1.1), knitr(v.1.43),
arrayhelpers(v.1.1-0), gridExtra(v.2.3),
V8(v.4.3.3), svglite(v.2.1.1),
stats4(v.4.3.1), xfun(v.0.39),
graphlayouts(v.1.0.0), bridgesampling(v.1.1-2),
matrixStats(v.1.0.0), rstan(v.2.26.22),
stringi(v.1.7.12), boot(v.1.3-28.1),
yaml(v.2.3.7), evaluate(v.0.21),
codetools(v.0.2-19), ggraph(v.2.1.0),
cli(v.3.6.1), RcppParallel(v.5.1.7),
shinythemes(v.1.2.0), xtable(v.1.8-4),
systemfonts(v.1.0.4), munsell(v.0.5.0),
processx(v.3.8.2), jquerylib(v.0.1.4),
coda(v.0.19-4), svUnit(v.1.0.6),
parallel(v.4.3.1), rstantools(v.2.3.1.1),
ellipsis(v.0.3.2), prettyunits(v.1.1.1),
dygraphs(v.1.1.1.6), bayesplot(v.1.10.0),
Brobdingnag(v.1.2-9), viridisLite(v.0.4.2),
mvtnorm(v.1.2-2), scales(v.1.2.1),
xts(v.0.13.1), crayon(v.1.5.2),
rlang(v.1.1.1), rvest(v.1.0.3) and
shinyjs(v.2.1.0)
LS0tDQp0aXRsZTogJ0FuIHVuZGVyZ3JhZHVhdGUgY2xhc3Nyb29tIGV4cGVyaW1lbnQgZGVtb25zdHJhdGVzIHRoZSBwb3RlbnRpYWwgb2Ygc3ViY29uc2Npb3VzIGJpYXMgdG8gaW5mbHVlbmNlIGRhdGEgY29sbGVjdGlvbiBpbiBhbmltYWwgYmVoYXZpb3VyJw0KYXV0aG9yOiAnVGhvbWFzIEtlYW5leSwgVGhlcmVzYSBKb25lcyBhbmQgUmFvdWwgTXVsZGVyJyANCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBkZXB0aDogMQ0KICAgIG51bWJlcl9zZWN0aW9uczogbm8NCiAgICB0aGVtZTogeWV0aQ0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQplZGl0b3Jfb3B0aW9uczoNCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIGNhY2hlID0gRkFMU0UpDQpgYGANCg0KIyBUZWFjaGluZyBtYXRlcmlhbHMNCg0KJH4kDQoNCioq4oCYaHVuZ3J5IGZvcmFnZXLigJkgcHJpbWVyKio6IA0KDQoqKuKAmHNhdGlhdGVkIGZvcmFnZXLigJkgcHJpbWVyKio6DQoNClBpZ2VvbiBmb290YWdlIGlzIGF2YWlsYWJsZSBvbiB0aGUgZ2l0aHViIHBhZ2UgYXNzb2NpYXRlZCB3aXRoIHRoaXMgcmVwb3J0LiBJdCBjYW4gYmUgYWNjZXNzZWQgaGVyZTogaHR0cHM6Ly9naXRodWIuY29tL3RvbWtlYW5leS9CaWFzZWRfcGlnZW9ucyBieSBkb3dubG9hZGluZyB0aGUgYHBpZ2Vvbl92aWRlby5tcDRgIGZpbGUuDQoNCiR+JA0KDQojIExvYWQgcGFja2FnZXMgYW5kIHRoZSBkYXRhDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpICMgdGlkeSBzdHlsZSBjb2RpbmcNCmxpYnJhcnkoYnJtcykgIyBCYXllc2lhbiBtb2RlbHMNCmxpYnJhcnkobG9vKSAjIGZvciBpbmZvcm1hdGlvbiBjcml0ZXJpYQ0KbGlicmFyeSh0aWR5YmF5ZXMpICMgQmF5ZXNpYW4gYWVzdGhldGljcw0KbGlicmFyeShNZXRCcmV3ZXIpICMgY29sb3Vycw0KbGlicmFyeShrYWJsZUV4dHJhKSAjIHRhYmxlcw0KbGlicmFyeShwYXRjaHdvcmspICMgcHV0dGluZyBwbG90cyB0b2dldGhlcg0KbGlicmFyeShEVCkgIyBmb3Igc2VhcmNoLSBhbmQgc2F2ZWFibGUgdGFibGVzDQpsaWJyYXJ5KHBhbmRlcikgIyBmb3Igc2ltcGxlciB0YWJsZXMNCmxpYnJhcnkocG5nKSAjIHRvIGxvYWQgaW1hZ2VzDQpsaWJyYXJ5KGdyaWQpICMgdG8gcGxvdCBpbWFnZXMNCmxpYnJhcnkoZ2dkYWcpICMgdG8gZHJhdyBkYWdzDQpgYGANCg0KYGBge3J9DQoNCmRhdGEgPC0gcmVhZF9jc3YoImRhdGEvcGlnZW9uX2RhdGEuY3N2IikgJT4lIA0KICBtdXRhdGUoU3R1ZGVudF9JRCA9IGFzLmZhY3RvcihTdHVkZW50X0lEKSwNCiAgICAgICAgIFllYXIgPSBhcy5mYWN0b3IoWWVhciksDQogICAgICAgICBGb3JhZ2luZ19wcm9wID0gKEZvcmFnaW5nX3BlcmNlbnRhZ2UgLyAxMDApKSAlPiUNCiAgZmlsdGVyKFllYXIgJWluJSBjKCIyMDIxIiwgIjIwMjIiLCAiMjAyMyIpLA0KICAgICAgICAgRm9yYWdpbmdfcGVyY2VudGFnZSAhPSAiTkEiLA0KICAgICAgICAgUHJpbWVyX3VuZGVyc3Rvb2QgIT0gIk5BIikgJT4lDQogIGZpbHRlcihTdHVkZW50X0lEICE9ICI2MCIgJiBTdHVkZW50X0lEICE9ICI2OCIgJiBTdHVkZW50X0lEICE9ICI3MCIgJiBTdHVkZW50X0lEICE9ICI3MiIpICU+JSAjIHJlbW92ZSBzdHVkZW50cyB0aGF0IGNvbXBsZXRlZCB0aGUgdGFzayBtdWx0aXBsZSB0aW1lcw0KICAjU3R1ZGVudF9JRCAlaW4lIGMoIjYwIiwgIjY4IiwgIjcwIiwgIjcyIikpICU+JSANCiAgc2VsZWN0KC1jKEZpcnN0X25hbWUsIFN1cm5hbWUsIFBlY2tfbWVhbikpICU+JSAgIyByZW1vdmUgbmFtZXMgd2hlbiByZWFkeQ0KICBsZWZ0X2pvaW4oDQogICAgcmVhZF9jc3YoImRhdGEvZ2VuZGVyX2RhdGEuY3N2IikgJT4lIA0KICAgICAgbXV0YXRlKFN0dWRlbnRfSUQgPSBhcy5mYWN0b3IoU3R1ZGVudF9JRCkpDQogICkgJT4lIA0KICByZW5hbWUoT2JzZXJ2ZXJfSUQgPSBTdHVkZW50X0lEKSAlPiUgDQogIHNlbGVjdChPYnNlcnZlcl9JRCwgWWVhciwgR2VuZGVyLCBldmVyeXRoaW5nKCkpDQoNCmRhdGFfcGVjayA8LSANCiAgZGF0YSAlPiUNCiAgZmlsdGVyKFBlY2tfcmF0ZV8yICE9ICJOQSIpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBQZWNrX3JhdGVfMTpQZWNrX3JhdGVfMiwgbmFtZXNfdG8gPSAiVHJpYWwiLA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIlBlY2tfcmF0ZSIpDQogIA0KIyBDcmVhdGUgYSBmdW5jdGlvbiB0byBidWlsZCBIVE1MIHNlYXJjaGFibGUgdGFibGVzDQoNCm15X2RhdGFfdGFibGUgPC0gZnVuY3Rpb24oZGYpew0KICBkYXRhdGFibGUoDQogICAgZGYsIHJvd25hbWVzPUZBTFNFLA0KICAgIGF1dG9IaWRlTmF2aWdhdGlvbiA9IFRSVUUsDQogICAgZXh0ZW5zaW9ucyA9IGMoIlNjcm9sbGVyIiwgICJCdXR0b25zIiksDQogICAgb3B0aW9ucyA9IGxpc3QoDQogICAgICBkb20gPSAnQmZydGlwJywNCiAgICAgIGRlZmVyUmVuZGVyPVRSVUUsDQogICAgICBzY3JvbGxYPVRSVUUsIHNjcm9sbFk9NDAwLA0KICAgICAgc2Nyb2xsQ29sbGFwc2U9VFJVRSwNCiAgICAgIGJ1dHRvbnMgPQ0KICAgICAgICBsaXN0KCdwYWdlTGVuZ3RoJywgJ2NvbHZpcycsICdjc3YnLCBsaXN0KA0KICAgICAgICAgIGV4dGVuZCA9ICdwZGYnLA0KICAgICAgICAgIHBhZ2VTaXplID0gJ0E0JywNCiAgICAgICAgICBvcmllbnRhdGlvbiA9ICdsYW5kc2NhcGUnLA0KICAgICAgICAgIGZpbGVuYW1lID0gJ2Z1bGxfZGF0YXNldCcpKSwNCiAgICAgIHBhZ2VMZW5ndGggPSA3OA0KICAgICkNCiAgKQ0KfQ0KDQpteV9kYXRhX3RhYmxlKGRhdGEpDQpgYGANCg0KKipDb2x1bW4gZXhwbGFuYXRpb25zKioNCg0KKipPYnNlcnZlcl9JRCoqOiB1bmlxdWUsIGFub255bWlzZWQgaWRlbnRpZmllciBmb3IgZWFjaCBvYnNlcnZlci4NCg0KKipZZWFyKio6IHllYXIgdGhhdCB0aGUgZXhwZXJpbWVudCB3YXMgY29uZHVjdGVkLg0KDQoqKkdlbmRlcioqOiB1cG9uIGVucm9sbG1lbnQgYXQgVGhlIFVuaXZlcnNpdHkgb2YgTWVsYm91cm5lLCBzdHVkZW50cyBhcmUgYXNrZWQgdG8gaW5kaWNhdGUgdGhlaXIgdGl0bGUuIFdlIGlkZW50aWZpZWQgd29tZW4gYXMgb2JzZXJ2ZXJzIHRoYXQgYW5zd2VyZWQgIk1pc3MiIG9yICJNcyIgYW5kIE1lbiBhcyB0aG9zZSB3aG8gdGhhdCBhbnN3ZXJlZCAiTXIiLiBUaG9zZSB3aXRoIGVudGlyZWx5IG1pc3NpbmcgZW50cmllcyB3ZXJlIGNvZGVkIGFzICJOQSIuICANCg0KKipCaWFzX3RyZWF0bWVudCoqOiB0aGUgcHJpbWVyIHRoZSBvYnNlcnZlciByZWNlaXZlZCwgd2hlcmUgJ3NhdGlhdGVkJyBpbmRpY2F0ZXMgdGhhdCB0aGUgb2JzZXJ2ZXJzIHdlcmUgcHJvdmlkZWQgaW5mb3JtYXRpb24gcHJpb3IgdG8gYSB0cmlhbCB0aGF0IHN1Z2dlc3RlZCBwaWdlb25zIHdlcmUgZmVsbCBmZWQsIHdoZXJlYXMgJ2h1bmdyeScgaW5kaWNhdGVkIHRoYXQgdGhlIHBpZ2VvbnMgd2VyZSBpbiBwb29yIGNvbmRpdGlvbiBhbmQgaHVuZ3J5Lg0KDQoqKkV4cGVjdGF0aW9uKio6IHdlIGFza2VkIHRoZSBvYnNlcnZlcnMgdG8gaW5kaWNhdGUgd2hldGhlciB0aGV5IHRob3VnaHQgdGhlIHBpZ2VvbnMgd291bGQgYmUgaHVuZ3J5IG9yIHNhdGlhdGVkLiBXZSBpbmNsdWRlZCB0aGlzIHF1ZXN0aW9uIHRvIHRlc3Qgd2hldGhlciBvYnNlcnZlcnMgd2VyZSBhcHByb3ByaWF0ZWx5IHByaW1lZCBieSB0aGVpciBiaWFzIHRyZWF0bWVudC4NCg0KKipQcmltZXJfdW5kZXJzdG9vZCoqOiBkaWQgdGhlIG9ic2VydmVyJ3MgZXhwZWN0YXRpb24gbWF0Y2ggdGhlIHByaW1lciB0aGV5IHJlY2VpdmVkPw0KDQoqKkZvcmFnaW5nX3BlcmNlbnRhZ2UqKjogdGhlIHBlcmNlbnRhZ2Ugb2YgcGlnZW9ucyB0aGF0IG9ic2VydmVycyBlc3RpbWF0ZWQgdG8gYmUgZm9yYWdpbmcgb3ZlciBhIDE1IHNlY29uZCBwZXJpb2QsIHdoaWxlIG9ic2VydmluZyBhIGxhcmdlIGZsb2NrLg0KDQoqKlBlY2tfcmF0ZV8xKio6IHRoZSBudW1iZXIgb2YgdGltZXMgYSBzaW5nbGUgY2hvc2VuIHBpZ2VvbiBwZWNrZWQgdGhlIGdyb3VuZCBvdmVyIGEgMTUgc2Vjb25kIHBlcmlvZC4NCg0KKipQZWNrX3JhdGVfMioqOiB0aGUgbnVtYmVyIG9mIHRpbWVzIGEgc2Vjb25kIGNob3NlbiBwaWdlb24gcGVja2VkIHRoZSBncm91bmQgb3ZlciBhIDE1IHNlY29uZCBwZXJpb2QuDQoNCioqRm9yYWdpbmdfcHJvcCoqOiBwcm9wb3J0aW9uIG9mIHBpZ2VvbnMgZXN0aW1hdGVkIHRvIGJlIGZvcmFnaW5nIA0KDQokfiQNCg0KIyBRdWVzdGlvbiAxOiBpcyBlc3RpbWF0aW9uIG9mIGZvcmFnaW5nIHBlcmNlbnRhZ2UgYWZmZWN0ZWQgYnkgYmlhcyBtYW5pcHVsYXRpb25zPw0KDQokfiQNCg0KIyMgRXhwbG9yaW5nIGFsbG9jYXRpb24gdmVyc3VzIGV4cGVjdGF0aW9uIDEgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KJH4kDQoNCldlIGZpbmQgdGhhdCAqKjIyIG9mIHRoZSA3OCBvYnNlcnZlcnMqKiBpbmRpY2F0ZWQgYSBmZWVkaW5nIG1vdGl2YXRpb24gZXhwZWN0YXRpb24gb3Bwb3NpdGUgdG8gdGhhdCBpbXBsaWVkIGJ5IHRoZSBwcmltZXIgdGhleSB3ZXJlIGFsbG9jYXRlZC4gDQoNClRoaXMgc3VnZ2VzdHMgdGhhdCBgRXhwZWN0YXRpb25gIG1heSBiZSBhIGJldHRlciBwcmVkaWN0b3Igb2YgZm9yYWdpbmcgZXN0aW1hdGlvbiB0aGFuIGFsbG9jYXRlZCBgQmlhc190cmVhdG1lbnRgLiBUaGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlc2UgYW5kIGFsbCBvdGhlciB2YXJpYWJsZXMgdGhhdCB3ZSBleHBlY3QgdG8gcGxheSBhIHJvbGUgaW4gdGhpcyBzeXN0ZW0gYXJlIGRlcGljdGVkIGluIEZpZ3VyZSAxLg0KDQpXZSBleHBsaWNpdGx5IGFzc2VzcyB0aGUgZWZmZWN0IG9mIHRyZWF0bWVudCBhbmQgZXhwZWN0YXRpb24gYnkgZml0dGluZyB0d28gbW9kZWxzOg0KDQoxLiBhIG1vZGVsIHdpdGggYWxsb2NhdGVkIHByaW1lciAoYEJpYXNfdHJlYXRtZW50YCkgYXMgdGhlIHByZWRpY3RvciB2YXJpYWJsZSANCg0KMi4gYSBtb2RlbCB3aXRoIGluZGljYXRlZCBodW5nZXIgZXhwZWN0YXRpb24gKGBFeHBlY3RhdGlvbmApIGFzIHRoZSBwcmVkaWN0b3IgdmFyaWFibGUNCg0KJH4kDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0KZ2dfc2ltcGxlX2RhZyA8LSBmdW5jdGlvbihkKSB7DQogIGQgJT4lIA0KICAgIGdncGxvdChhZXMoeCA9IHgsIHkgPSB5LCB4ZW5kID0geGVuZCwgeWVuZCA9IHllbmQsIGNvbG91ciA9IFZhcmlhYmxlcykpICsNCiAgICBnZW9tX2RhZ19wb2ludCgpICsNCiAgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIkluY2x1ZGVkIGluIG1vZGVsIiA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIpWzRdLCAiTm90IGluY2x1ZGVkIGluIG1vZGVsIiA9ICJncmV5ODAiKSkgKw0KICAgIGdlb21fZGFnX3RleHQoY29sb3IgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiKVs3XSkgKw0KICAgIGdlb21fZGFnX2VkZ2VzKCkgKyANCiAgICB0aGVtZV9kYWcoKSsNCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwNCiAgICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpDQp9DQoNCg0Kb2JzZXJ2ZXJfYmlhc19kYWcgPC0gZGFnaWZ5KEVGIH4gUEVXICsgUEVNICsgU0IgKyBURiwNCiAgICAgICAgUEVXIH4gQlQsDQogICAgICAgIFBFTSB+IEJULA0KICAgICAgICBTQiB+IFBFVyArIFBFTSwNCiAgICAgICBsYWJlbHMgPSBjKCJURiIgPSAiVHJ1ZVxuIEZvcmFnaW5nIiwgDQogICAgICAgICAgICAgICAgICAiRUYiID0gIkVzdGltYXRlZFxuIEZvcmFnaW5nIiwNCiAgICAgICAgICAgICAgICAgICJQRVciID0gIlByaW9yXG4gRXhwZWN0YXRpb24gTWVuIiwNCiAgICAgICAgICAgICAgICAgICJQRU0iID0gIlByaW9yXG4gRXhwZWN0YXRpb24gV29tZW4iLA0KICAgICAgICAgICAgICAgICAgIkJUIiA9ICJCaWFzXG4gVHJlYXRtZW50IiwNCiAgICAgICAgICAgICAgICAgICJTQiIgPSAiU2VsZWN0aW9uXG4gQmlhcyIpKSAlPiUgDQogIHRpZHlfZGFnaXR0eShzZWVkID0gNSkNCiAgDQogIA0KIG9ic2VydmVyX2JpYXNfZGFnIDwtIGxlZnRfam9pbihvYnNlcnZlcl9iaWFzX2RhZyRkYXRhLCB0aWJibGUobmFtZSA9IGMoIkJUIiwgIkVGIiwgIlBFVyIsICJQRU0iLCAiU0IiLCAiVEYiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFyaWFibGVzID0gYygiSW5jbHVkZWQgaW4gbW9kZWwiLCAiSW5jbHVkZWQgaW4gbW9kZWwiLCAiSW5jbHVkZWQgaW4gbW9kZWwiLCAiSW5jbHVkZWQgaW4gbW9kZWwiLCAiTm90IGluY2x1ZGVkIGluIG1vZGVsIiwgIk5vdCBpbmNsdWRlZCBpbiBtb2RlbCIpKSkgJT4lIA0KICAgDQogZ2dfc2ltcGxlX2RhZygpDQoNCg0Kb2JzZXJ2ZXJfYmlhc19kYWcNCg0KIyoqRmlndXJlIDEqKi4gQSBkaXJlY3QgYWNyeWxpYyBkaWFncmFtIHNob3dpbmcgdGhlIGZsb3cgb2YgY2F1c2F0aW9uIGluIG91ciBiaW9sb2dpY2FsIHN5c3RlbS4gT3VyIGJpYXMgdHJlYXRtZW50IChCVCkgd2FzIGRlc2lnbmVkIHRvIGFmZmVjdCB0aGUgcHJpb3IgZXhwZWN0YXRpb24gKFBFKSBvZiBvYnNlcnZlcidzLCBhIHN1YnNldCBvZiB3aGljaCB3ZXJlIHdvbWVuIChQRVcpLCB3aGlsZSB0aGUgcmVtYWluaW5nIHdlcmUgbWVuIChQRU0pLiBQcmlvciBleHBlY3RhdGlvbnMgbWF5IGFmZmVjdCB0aGUgZXN0aW1hdGVkIGxldmVsIG9mIGZvcmFnaW5nIChFRikgZGlyZWN0bHksIG9yIG1vcmUgc3BlY2lmaWNhbGx5IHRocm91Z2ggYmlhc2VkIHNlbGVjdGlvbiBvZiBwYXJ0aWN1bGFyIGZvcmFnZXJzIChTQikuIEVzdGltYXRlZCBmb3JhZ2luZyBpcyBhbHNvIGFmZmVjdGVkIGJ5IHRoZSB0cnVlIGxldmVsIG9mIGZvcmFnaW5nIChURikgY2FycmllZCBvdXQgYnkgdGhlIGZsb2NrIG9mIHBpZ2VvbnMgaW4gdGhlIGZvb3RhZ2UuIFdlIGh5cG90aGVzaXNlZCB0aGF0IF9hIHByaW9yaV8gZXhwZWN0YXRpb25zIG9mIG9ic2VydmVyJ3Mgd291bGQgYWZmZWN0IHRoZWlyIGZvcmFnaW5nIGVzdGltYXRlcy4gVGhlIHBhdGhzIGNvbm5lY3RpbmcgY29sb3VyZWQgdmFyaWFibGVzIHNob3cgdGhhdCB0aGlzIGNhbiBiZSB0ZXN0ZWQgYnkgbW9kZWxsaW5nIHRoZSBlZmZlY3Qgb2YgYmlhcyB0cmVhdG1lbnQgb24gZXN0aW1hdGVkIGZvcmFnaW5nLCBvciBhbHRlcm5hdGl2ZWx5IGJ5IGRpcmVjdGx5IG1vZGVsbGluZyB0aGUgZWZmZWN0IG9mIHByaW9yIGV4cGVjdGF0aW9uIG9uIGVzdGltYXRlZCBmb3JhZ2luZy4gDQoNCg0KYGBgDQoNCg0KJH4kDQoNCiMjIyBNb2RlbCAxOiBhbGxvY2F0ZWQgcHJpbWVyDQoNCmBgYHtyfQ0KDQojIEZpcnN0IGxldCdzIG1vZGVsIHRoZSBlZmZlY3Qgb2YgYmlhcyB0cmVhdG1lbnQgb24gZm9yYWdpbmcgZXN0aW1hdGlvbiANCg0KZm9yYWdpbmdfbW9kZWxfdHJlYXRtZW50IDwtIGJybShGb3JhZ2luZ19wcm9wIH4gMCArIEJpYXNfdHJlYXRtZW50LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCBmYW1pbHkgPSBCZXRhLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMS41KSwgY2xhc3MgPSBiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gcGhpKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlciA9IDYwMDAsIHdhcm11cCA9IDIwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOCwgbWF4X3RyZWVkZXB0aCA9IDEwKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkID0gMSwgZmlsZSA9ICJmaXRzL2ZvcmFnaW5nX21vZGVsX3RyZWF0bWVudCIpDQoNCmZvcmFnaW5nX21vZGVsX3RyZWF0bWVudCA8LSBhZGRfY3JpdGVyaW9uKGZvcmFnaW5nX21vZGVsX3RyZWF0bWVudCwgY3JpdGVyaW9uID0gImxvbyIsIGZpbGUgPSAiZml0cy9mb3JhZ2luZ19tb2RlbF90cmVhdG1lbnQiKQ0KDQpmb3JhZ2luZ19tb2RlbF90cmVhdG1lbnQNCg0KZm9yYWdpbmdfbW9kZWxfdHJlYXRtZW50X2dlbmRlciA8LSBicm0oRm9yYWdpbmdfcHJvcCB+IDAgKyBHZW5kZXIgKiBCaWFzX3RyZWF0bWVudCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgZmFtaWx5ID0gQmV0YSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvciA9IGMocHJpb3Iobm9ybWFsKDAsIDEuNSksIGNsYXNzID0gYiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHBoaSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIgPSA2MDAwLCB3YXJtdXAgPSAyMDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjgsIG1heF90cmVlZGVwdGggPSAxMCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZCA9IDEsIGZpbGUgPSAiZml0cy9mb3JhZ2luZ19tb2RlbF90cmVhdG1lbnRfZ2VuZGVyIikNCg0KYGBgDQoNCioqVGFibGUgUzEqKi4gUG9zdGVyaW9yIGVzdGltYXRlcyBvZiB0aGUgcGVyY2VudGFnZSBvZiBwaWdlb24gZmVlZGluZyByYXRlLCBzcGxpdCBieSB0aGUgcHJpbWVyIG9ic2VydmVycyB3ZXJlIGFsbG9jYXRlZC4NCg0KYGBge3J9DQpuZXdfZGF0YSA8LSB0aWJibGUoQmlhc190cmVhdG1lbnQgPSBjKCJIdW5ncnkiLCAiU2F0aWF0ZWQiKSkNCg0KbmV3X2RhdGEgJT4lIA0KICBsZWZ0X2pvaW4oZGF0YSAlPiUgZ3JvdXBfYnkoQmlhc190cmVhdG1lbnQpICU+JSBzdW1tYXJpc2UoYG4gb2JzZXJ2ZXJzYCA9IG4oKSkpICU+JSANCiAgY2JpbmQoZml0dGVkKGZvcmFnaW5nX21vZGVsX3RyZWF0bWVudCwgbmV3ZGF0YSA9IG5ld19kYXRhLCBzdW1tYXJ5ID0gVCkgJT4lIA0KICAgICAgICAgIGFzX3RpYmJsZSgpICU+JSANCiAgICAgICAgICBtdXRhdGUoYWNyb3NzKDE6NCwgfiAueCAqMTAwKSwNCiAgICAgICAgICAgICAgICAgYWNyb3NzKDE6NCwgcm91bmQsIDIpKSkgJT4lIA0KICByZW5hbWUoIkVzdGltYXRlZCBwcm9wb3J0aW9uIGZvcmFnaW5nIiA9IEVzdGltYXRlLA0KICAgICAgICAgIkJpYXMgdHJlYXRtZW50IiA9IEJpYXNfdHJlYXRtZW50KSAlPiUgDQogIHBhbmRlcihzcGxpdC5jZWxsID0gMjAsIHNwbGl0LnRhYmxlID0gSW5mKQ0KDQpgYGANCg0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCiMgYWRkIGdlbmRlciBwcmVkaWN0aW9ucw0KDQpuZXdfZGF0YV9nZW5kZXIgPC0gZXhwYW5kX2dyaWQoQmlhc190cmVhdG1lbnQgPSBjKCJIdW5ncnkiLCAiU2F0aWF0ZWQiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5kZXIgPSBjKCJXb21hbiIsICJNYW4iKSkNCg0KbmV3X2RhdGFfZ2VuZGVyICU+JSANCiAgbGVmdF9qb2luKGRhdGEgJT4lIGdyb3VwX2J5KEdlbmRlciwgQmlhc190cmVhdG1lbnQpICU+JSBzdW1tYXJpc2UoYG4gb2JzZXJ2ZXJzYCA9IG4oKSkgJT4lIA0KICAgICAgICAgIHVuZ3JvdXAoKSAlPiUgZmlsdGVyKCFpcy5uYShHZW5kZXIpKSkgJT4lIA0KICBjYmluZChmaXR0ZWQoZm9yYWdpbmdfbW9kZWxfdHJlYXRtZW50X2dlbmRlciwgbmV3ZGF0YSA9IG5ld19kYXRhX2dlbmRlciwgc3VtbWFyeSA9IFQpICU+JSANCiAgICAgICAgICBhc190aWJibGUoKSAlPiUgDQogICAgICAgICAgbXV0YXRlKGFjcm9zcygxOjQsIH4gLnggKjEwMCksDQogICAgICAgICAgICAgICAgIGFjcm9zcygxOjQsIHJvdW5kLCAyKSkpICU+JSANCiAgcmVuYW1lKCJFc3RpbWF0ZWQgcHJvcG9ydGlvbiBmb3JhZ2luZyIgPSBFc3RpbWF0ZSwNCiAgICAgICAgICJCaWFzIHRyZWF0bWVudCIgPSBCaWFzX3RyZWF0bWVudCkgJT4lIA0KICBwYW5kZXIoc3BsaXQuY2VsbCA9IDIwLCBzcGxpdC50YWJsZSA9IEluZikNCmBgYA0KDQoNCiMjIyBNb2RlbCAyOiBpbmRpY2F0ZWQgZXhwZWN0YXRpb24NCg0KYGBge3J9DQoNCiMgZml0IHRoZSBzYW1lIG1vZGVsLCBleGNlcHQgdXNpbmcgcGFydGljaXBhbnQgZXhwZWN0YXRpb24gcmF0aGVyIHRoYW4gYWxsb2NhdGVkIGJpYXMgdHJlYXRtZW50DQoNCmZvcmFnaW5nX21vZGVsX2V4cGVjdGF0aW9uIDwtIGJybShGb3JhZ2luZ19wcm9wIH4gMCArIEV4cGVjdGF0aW9uLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLCBmYW1pbHkgPSBCZXRhLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMS41KSwgY2xhc3MgPSBiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gcGhpKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlciA9IDYwMDAsIHdhcm11cCA9IDIwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOCwgbWF4X3RyZWVkZXB0aCA9IDEwKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkID0gMSwgZmlsZSA9ICJmaXRzL2ZvcmFnaW5nX21vZGVsX2V4cGVjdGF0aW9uIikNCg0KZm9yYWdpbmdfbW9kZWxfZXhwZWN0YXRpb24gPC0gYWRkX2NyaXRlcmlvbihmb3JhZ2luZ19tb2RlbF9leHBlY3RhdGlvbiwgY3JpdGVyaW9uID0gImxvbyIsIGZpbGUgPSAiZml0cy9mb3JhZ2luZ19tb2RlbF9leHBlY3RhdGlvbiIpDQoNCmZvcmFnaW5nX21vZGVsX2V4cGVjdGF0aW9uDQoNCmZvcmFnaW5nX21vZGVsX2V4cGVjdGF0aW9uX2dlbmRlciA8LSBicm0oRm9yYWdpbmdfcHJvcCB+IDAgKyBHZW5kZXIgKiBFeHBlY3RhdGlvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwgZmFtaWx5ID0gQmV0YSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvciA9IGMocHJpb3Iobm9ybWFsKDAsIDEuNSksIGNsYXNzID0gYiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHBoaSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXIgPSA2MDAwLCB3YXJtdXAgPSAyMDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGxpc3QoYWRhcHRfZGVsdGEgPSAwLjgsIG1heF90cmVlZGVwdGggPSAxMCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZCA9IDEsIGZpbGUgPSAiZml0cy9mb3JhZ2luZ19tb2RlbF9leHBlY3RhdGlvbl9nZW5kZXIiKQ0KDQpgYGANCg0KKipUYWJsZSBTMioqLiBQb3N0ZXJpb3IgZXN0aW1hdGVzIG9mIHRoZSBwZXJjZW50YWdlIG9mIHBpZ2VvbnMgZm9yYWdpbmcsIHNwbGl0IGJ5IHRoZSBhY3R1YWwgZXhwZWN0YXRpb24gb2Ygb2JzZXJ2ZXJzLg0KDQpgYGB7cn0NCg0KbmV3X2RhdGFfMiA8LSB0aWJibGUoRXhwZWN0YXRpb24gPSBjKCJIdW5ncnkiLCAiU2F0aWF0ZWQiKSkNCg0KbmV3X2RhdGFfMiAlPiUgDQogICBsZWZ0X2pvaW4oZGF0YSAlPiUgZ3JvdXBfYnkoRXhwZWN0YXRpb24pICU+JSBzdW1tYXJpc2UoYG4gb2JzZXJ2ZXJzYCA9IG4oKSkpICU+JSANCiAgY2JpbmQoZml0dGVkKGZvcmFnaW5nX21vZGVsX2V4cGVjdGF0aW9uLCBuZXdkYXRhID0gbmV3X2RhdGFfMiwgc3VtbWFyeSA9IFQpICU+JSANCiAgICAgICAgICBhc190aWJibGUoKSAlPiUgDQogICAgICAgICAgbXV0YXRlKGFjcm9zcygxOjQsIH4gLnggKjEwMCksDQogICAgICAgICAgICAgICAgIGFjcm9zcygxOjQsIHJvdW5kLCAyKSkpICU+JSAgDQogIHJlbmFtZSgiRXN0aW1hdGVkIHByb3BvcnRpb24gZm9yYWdpbmciID0gRXN0aW1hdGUsDQogICAgICAgICAiSW5kaWNhdGVkIGV4cGVjdGF0aW9uIiA9IEV4cGVjdGF0aW9uKSAlPiUgDQogIHBhbmRlcihzcGxpdC5jZWxsID0gMjAsIHNwbGl0LnRhYmxlID0gSW5mKQ0KDQpgYGANCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQojIGFkZCBnZW5kZXIgcHJlZGljdGlvbnMNCg0KbmV3X2RhdGFfZ2VuZGVyXzIgPC0gZXhwYW5kX2dyaWQoRXhwZWN0YXRpb24gPSBjKCJIdW5ncnkiLCAiU2F0aWF0ZWQiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5kZXIgPSBjKCJXb21hbiIsICJNYW4iKSkNCg0KbmV3X2RhdGFfZ2VuZGVyXzIgJT4lIA0KICBsZWZ0X2pvaW4oZGF0YSAlPiUgZ3JvdXBfYnkoRXhwZWN0YXRpb24sIEdlbmRlcikgJT4lIHN1bW1hcmlzZShgbiBvYnNlcnZlcnNgID0gbigpKSAlPiUgDQogICAgICAgICAgdW5ncm91cCgpICU+JSBmaWx0ZXIoIWlzLm5hKEdlbmRlcikpKSAlPiUNCiAgY2JpbmQoZml0dGVkKGZvcmFnaW5nX21vZGVsX2V4cGVjdGF0aW9uX2dlbmRlciwgDQogICAgICAgICAgICAgICBuZXdkYXRhID0gbmV3X2RhdGFfZ2VuZGVyXzIsIHN1bW1hcnkgPSBUKSAlPiUgDQogICAgICAgICAgYXNfdGliYmxlKCkgJT4lIA0KICAgICAgICAgIG11dGF0ZShhY3Jvc3MoMTo0LCB+IC54ICoxMDApLA0KICAgICAgICAgICAgICAgICBhY3Jvc3MoMTo0LCByb3VuZCwgMikpKSAlPiUgDQogIHJlbmFtZSgiRXN0aW1hdGVkIHByb3BvcnRpb24gZm9yYWdpbmciID0gRXN0aW1hdGUsDQogICAgICAgICAiSW5kaWNhdGVkIGV4cGVjdGF0aW9uIiA9IEV4cGVjdGF0aW9uKSAlPiUgDQogIHBhbmRlcihzcGxpdC5jZWxsID0gMjAsIHNwbGl0LnRhYmxlID0gSW5mKQ0KYGBgDQoNCg0KJH4kDQoNCiMjIEJ1aWxkIEZpZ3VyZSAxYS1kDQoNCiR+JA0KDQoqKkdldCBwb3N0ZXJpb3IgbWVhbnMgYW5kIGRpZmZlcmVuY2UgY29udHJhc3RzKioNCg0KYGBge3J9DQoNCiMgdHJlYXRtZW50IG1vZGVsDQoNCmRyYXdzX3RyZWF0bWVudCA8LQ0KICBhc19kcmF3c19kZihmb3JhZ2luZ19tb2RlbF90cmVhdG1lbnQpICU+JSANCiAgbXV0YXRlKEh1bmdyeSA9IGludl9sb2dpdF9zY2FsZWQoYl9CaWFzX3RyZWF0bWVudEh1bmdyeSkgKjEwMCwNCiAgICAgICAgIFNhdGlhdGVkID0gaW52X2xvZ2l0X3NjYWxlZChiX0JpYXNfdHJlYXRtZW50U2F0aWF0ZWQpKjEwMCwNCiAgICAgICAgIGRpZmZfY29udHJhc3QgPSAoSHVuZ3J5IC0gU2F0aWF0ZWQpKSAlPiUgDQogIHNlbGVjdChIdW5ncnksIFNhdGlhdGVkLCBkaWZmX2NvbnRyYXN0KSAlPiUgDQogIHBpdm90X2xvbmdlcihuYW1lc190byA9ICJUcmVhdG1lbnQiLCB2YWx1ZXNfdG8gPSAiUG9zdGVyaW9yX2VzdGltYXRlIiwgY29scyA9IDE6MykgJT4lIA0KICBtdXRhdGUoUHJlZGljdG9yID0gIkFsbG9jYXRlZCBwcmltZXIiKQ0KDQpwMiA8LSANCiAgZHJhd3NfdHJlYXRtZW50ICU+JSANCiAgZmlsdGVyKFRyZWF0bWVudCAhPSAiZGlmZl9jb250cmFzdCIpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gVHJlYXRtZW50LCB5ID0gUG9zdGVyaW9yX2VzdGltYXRlKSkgKyANCiAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gVHJlYXRtZW50KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSA0LCBzdHJva2UgPSAxLjUpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMikpICsNCiAgY29vcmRfZmxpcCh5bGltID0gYygyNSwgNTUpKSArDQogICNnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsNCiAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsNCiAgeGxhYigiQWxsb2NhdGVkIHByaW1lciIpICsNCiAgeWxhYigiRXN0aW1hdGVkICUgcGlnZW9ucyBmb3JhZ2luZyIpICsNCiAgdGhlbWVfYncoKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkNCg0KcDMgPC0NCiAgZHJhd3NfdHJlYXRtZW50ICU+JSANCiAgZmlsdGVyKFRyZWF0bWVudCA9PSAiZGlmZl9jb250cmFzdCIpICU+JSANCiAgZ2dwbG90KGFlcyh5ID0gUG9zdGVyaW9yX2VzdGltYXRlKSkgKyANCiAgIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IFRyZWF0bWVudCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMC45LA0KICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVkaWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LCBzY2FsZSA9MC41KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIpWzRdKSArDQogIGNvb3JkX2ZsaXAoeWxpbSA9IGMoLTIwLCAyMCkpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyLCBsaW5ld2lkdGggPSAwLjc1KSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygsIDAsIDEpKSArDQogIHhsYWIoTlVMTCkgKw0KICB5bGFiKCJIdW5ncnkgLSBTYXRpYXRlZCBkaWZmZXJlbmNlXG5jb250cmFzdCAoJSBwb2ludHMpIikgKw0KICB0aGVtZV9idygpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpDQoNCiMgZXhwZWN0YXRpb24gbW9kZWwNCg0KZHJhd3NfZXhwZWN0YXRpb24gPC0NCiAgYXNfZHJhd3NfZGYoZm9yYWdpbmdfbW9kZWxfZXhwZWN0YXRpb24pICU+JSANCiAgbXV0YXRlKEh1bmdyeSA9IGludl9sb2dpdF9zY2FsZWQoYl9FeHBlY3RhdGlvbkh1bmdyeSkgKjEwMCwNCiAgICAgICAgIFNhdGlhdGVkID0gaW52X2xvZ2l0X3NjYWxlZChiX0V4cGVjdGF0aW9uU2F0aWF0ZWQpKjEwMCwNCiAgICAgICAgIGRpZmZfY29udHJhc3QgPSAoSHVuZ3J5IC0gU2F0aWF0ZWQpKSAlPiUgDQogIHNlbGVjdChIdW5ncnksIFNhdGlhdGVkLCBkaWZmX2NvbnRyYXN0KSAlPiUgDQogIHBpdm90X2xvbmdlcihuYW1lc190byA9ICJUcmVhdG1lbnQiLCB2YWx1ZXNfdG8gPSAiUG9zdGVyaW9yX2VzdGltYXRlIiwgY29scyA9IDE6MykgJT4lIA0KICBtdXRhdGUoUHJlZGljdG9yID0gIkluZGljYXRlZCBleHBlY3RhdGlvbiIpDQoNCnA0IDwtDQogIGRyYXdzX2V4cGVjdGF0aW9uICU+JSANCiAgZmlsdGVyKFRyZWF0bWVudCAhPSAiZGlmZl9jb250cmFzdCIpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gVHJlYXRtZW50LCB5ID0gUG9zdGVyaW9yX2VzdGltYXRlKSkgKyANCiAgIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IFRyZWF0bWVudCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMC45LA0KICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVkaWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDIpKSArDQogIGNvb3JkX2ZsaXAoeWxpbSA9IGMoMjUsIDU1KSkgKw0KICAjZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygsIDAsIDEpKSArDQogIHhsYWIoIkluZGljYXRlZCBleHBlY3RhdGlvbiIpICsNCiAgeWxhYigiRXN0aW1hdGVkICUgcGlnZW9ucyBmb3JhZ2luZyIpICsNCiAgdGhlbWVfYncoKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkNCg0KcDUgPC0NCiAgZHJhd3NfZXhwZWN0YXRpb24gJT4lIA0KICBmaWx0ZXIoVHJlYXRtZW50ID09ICJkaWZmX2NvbnRyYXN0IikgJT4lIA0KICBnZ3Bsb3QoYWVzKHkgPSBQb3N0ZXJpb3JfZXN0aW1hdGUpKSArIA0KICAgIHN0YXRfaGFsZmV5ZShhZXMoZmlsbCA9IFRyZWF0bWVudCksIC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMC45LA0KICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVkaWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LCBzY2FsZSA9MC41KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIpWzRdKSArDQogIGNvb3JkX2ZsaXAoeWxpbSA9IGMoLTIwLCAyMCkpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyLCBsaW5ld2lkdGggPSAwLjc1KSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygsIDAsIDEpKSArDQogIHhsYWIoTlVMTCkgKw0KICB5bGFiKCJIdW5ncnkgLSBTYXRpYXRlZCBkaWZmZXJlbmNlXG5jb250cmFzdCAoJSBwb2ludHMpIikgKw0KICB0aGVtZV9idygpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpDQpgYGANCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQoNCiMgdHJlYXRtZW50IG1vZGVsDQoNCmdlbmRlcl90cmVhdG1lbnRfZHJhd3MgPC0NCiAgZml0dGVkKGZvcmFnaW5nX21vZGVsX3RyZWF0bWVudF9nZW5kZXIsIA0KICAgICAgICAgbmV3ZGF0YSA9IG5ld19kYXRhX2dlbmRlciwgc3VtbWFyeSA9IEYpICU+JSANCiAgYXNfdGliYmxlKCkgJT4lIA0KICByZW5hbWUoSHVuZ3J5X1dvbWVuID0gVjEsIEh1bmdyeV9NZW4gPSBWMiwgU2F0aWF0ZWRfV29tZW4gPSBWMywgU2F0aWF0ZWRfTWVuID0gVjQpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjQsIG5hbWVzX3RvID0gIkdyb3VwIiwgdmFsdWVzX3RvID0gIlBvc3Rlcmlvcl9lc3RpbWF0ZSIpICU+JSANCiAgc2VwYXJhdGUoc2VwID0gIl8iLCBjb2wgPSBHcm91cCwgaW50byA9IGMoIlRyZWF0bWVudCIsICJHZW5kZXIiKSkgJT4lDQogIG11dGF0ZShQb3N0ZXJpb3JfZXN0aW1hdGUgPSBQb3N0ZXJpb3JfZXN0aW1hdGUqMTAwKSANCiAgDQpjYWxjdWxhdGVfYWxsX3RoZV9kaWZmcyA8LQ0KICBmaXR0ZWQoZm9yYWdpbmdfbW9kZWxfdHJlYXRtZW50X2dlbmRlciwgDQogICAgICAgICBuZXdkYXRhID0gbmV3X2RhdGFfZ2VuZGVyLCBzdW1tYXJ5ID0gRikgJT4lIA0KICBhc190aWJibGUoKSAlPiUgDQogIHJlbmFtZShIdW5ncnlfV29tYW4gPSBWMSwgSHVuZ3J5X01hbiA9IFYyLCBTYXRpYXRlZF9Xb21hbiA9IFYzLCBTYXRpYXRlZF9NYW4gPSBWNCkgJT4lIA0KICBtdXRhdGUoV29tYW5faF9zX2RpZmYgPSBIdW5ncnlfV29tYW4gLSBTYXRpYXRlZF9Xb21hbiwNCiAgICAgICAgIE1hbl9oX3NfZGlmZiA9IEh1bmdyeV9NYW4gLSBTYXRpYXRlZF9NYW4sDQogICAgICAgICBkaWZmX2RpZmYgPSBXb21hbl9oX3NfZGlmZiAtIE1hbl9oX3NfZGlmZikgJT4lIA0KICBzZWxlY3QoY29udGFpbnMoImRpZmYiKSkgJT4lDQogIHJlbmFtZShgSC1TICh3b21lbilgID0gV29tYW5faF9zX2RpZmYsDQogICAgICAgICBgSC1TIChtZW4pYCA9IE1hbl9oX3NfZGlmZiwNCiAgICAgICAgIGBJbnRlcmFjdGlvbmAgPSBkaWZmX2RpZmYpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjMsIG5hbWVzX3RvID0gImRpZmZfY29udHJhc3QiLCB2YWx1ZXNfdG8gPSAicG9zdGVyaW9yX2RpZmYiKSAlPiUgDQogIG11dGF0ZShwb3N0ZXJpb3JfZGlmZiA9IHBvc3Rlcmlvcl9kaWZmKjEwMCkNCiAgDQoNCmdwMSA8LSANCiAgZ2VuZGVyX3RyZWF0bWVudF9kcmF3cyAlPiUgDQogIGdncGxvdChhZXMoeCA9IEdlbmRlciwgeSA9IFBvc3Rlcmlvcl9lc3RpbWF0ZSkpICsgDQogICAgc3RhdF9zbGFiKGFscGhhID0gMC44LCBzaGFwZSA9IDIxLCBhZXMoZmlsbCA9IFRyZWF0bWVudCkpICsNCiAgI3N0YXRfaGFsZmV5ZSgud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwNCiAgICMgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICMgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LA0KICAgIyAgICAgICAgICAgIGZpbGwgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCA1KVsyXSkgKw0KICAjc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMikpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYyhtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAxMClbNF0sIG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDEwKVs2XSkpICsNCiAgY29vcmRfZmxpcCgpKyN5bGltID0gYygyNSwgNTUpKSArDQogICNnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsNCiAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsNCiAgbGFicyh4ID0gIkdlbmRlciIsIHkgPSAiRXN0aW1hdGVkICUgcGlnZW9ucyBmb3JhZ2luZyIsIGZpbGwgPSAiQWxsb2NhdGVkXG5wcmltZXIiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpDQoNCg0KDQpncDIgPC0NCiAgY2FsY3VsYXRlX2FsbF90aGVfZGlmZnMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkaWZmX2NvbnRyYXN0LCB5ID0gcG9zdGVyaW9yX2RpZmYpKSArIA0KICAgICNzdGF0X3NsYWIoYWxwaGEgPSAwLjksIHNoYXBlID0gMjEsIGFlcyhmaWxsID0gR2VuZGVyKSkgKw0KICBzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSAzLCBzdHJva2UgPSAxLjUsDQogICAgICAgICAgICAgICBmaWxsID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMTApWzVdKSArDQogICNzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAyKSkgKw0KICBjb29yZF9mbGlwKCkrI3lsaW0gPSBjKDI1LCA1NSkpICsNCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMiwgbGluZXdpZHRoID0gMC43NSkgKw0KICAjZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygsIDAsIDEpKSArDQogIHhsYWIoIkRpZmZlcmVuY2UgY29udHJhc3QiKSArDQogIHlsYWIoIiUgcG9pbnRzIikgKw0KICB0aGVtZV9idygpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQ0KDQojIGV4cGVjdGF0aW9uIG1vZGVsDQoNCmdlbmRlcl9leHBlY3RhdGlvbl9kcmF3cyA8LQ0KICBmaXR0ZWQoZm9yYWdpbmdfbW9kZWxfZXhwZWN0YXRpb25fZ2VuZGVyLCANCiAgICAgICAgIG5ld2RhdGEgPSBuZXdfZGF0YV9nZW5kZXJfMiwgc3VtbWFyeSA9IEYpICU+JSANCiAgYXNfdGliYmxlKCkgJT4lIA0KICByZW5hbWUoSHVuZ3J5X1dvbWVuID0gVjEsIEh1bmdyeV9NZW4gPSBWMiwgU2F0aWF0ZWRfV29tZW4gPSBWMywgU2F0aWF0ZWRfTWVuID0gVjQpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjQsIG5hbWVzX3RvID0gIkdyb3VwIiwgdmFsdWVzX3RvID0gIlBvc3Rlcmlvcl9lc3RpbWF0ZSIpICU+JSANCiAgc2VwYXJhdGUoc2VwID0gIl8iLCBjb2wgPSBHcm91cCwgaW50byA9IGMoIlRyZWF0bWVudCIsICJHZW5kZXIiKSkgJT4lDQogIG11dGF0ZShQb3N0ZXJpb3JfZXN0aW1hdGUgPSBQb3N0ZXJpb3JfZXN0aW1hdGUqMTAwKSANCiAgDQpjYWxjdWxhdGVfYWxsX3RoZV9kaWZmc18yIDwtDQogIGZpdHRlZChmb3JhZ2luZ19tb2RlbF9leHBlY3RhdGlvbl9nZW5kZXIsIA0KICAgICAgICAgbmV3ZGF0YSA9IG5ld19kYXRhX2dlbmRlcl8yLCBzdW1tYXJ5ID0gRikgJT4lIA0KICBhc190aWJibGUoKSAlPiUgDQogIHJlbmFtZShIdW5ncnlfV29tYW4gPSBWMSwgSHVuZ3J5X01hbiA9IFYyLCBTYXRpYXRlZF9Xb21hbiA9IFYzLCBTYXRpYXRlZF9NYW4gPSBWNCkgJT4lIA0KICBtdXRhdGUoV29tYW5faF9zX2RpZmYgPSBIdW5ncnlfV29tYW4gLSBTYXRpYXRlZF9Xb21hbiwNCiAgICAgICAgIE1hbl9oX3NfZGlmZiA9IEh1bmdyeV9NYW4gLSBTYXRpYXRlZF9NYW4sDQogICAgICAgICBkaWZmX2RpZmYgPSBXb21hbl9oX3NfZGlmZiAtIE1hbl9oX3NfZGlmZikgJT4lIA0KICBzZWxlY3QoY29udGFpbnMoImRpZmYiKSkgJT4lDQogIHJlbmFtZShgSC1TICh3b21lbilgID0gV29tYW5faF9zX2RpZmYsDQogICAgICAgICBgSC1TIChtZW4pYCA9IE1hbl9oX3NfZGlmZiwNCiAgICAgICAgIGBJbnRlcmFjdGlvbmAgPSBkaWZmX2RpZmYpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjMsIG5hbWVzX3RvID0gImRpZmZfY29udHJhc3QiLCB2YWx1ZXNfdG8gPSAicG9zdGVyaW9yX2RpZmYiKSAlPiUgDQogIG11dGF0ZShwb3N0ZXJpb3JfZGlmZiA9IHBvc3Rlcmlvcl9kaWZmKjEwMCkNCg0KZ3AzIDwtIA0KICBnZW5kZXJfZXhwZWN0YXRpb25fZHJhd3MgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBHZW5kZXIsIHkgPSBQb3N0ZXJpb3JfZXN0aW1hdGUpKSArIA0KICAgIHN0YXRfc2xhYihhbHBoYSA9IDAuOSwgc2hhcGUgPSAyMSwgYWVzKGZpbGwgPSBUcmVhdG1lbnQpKSArDQogICNzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAjICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVkaWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsDQogICAjICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwNCiAgICMgICAgICAgICAgICBmaWxsID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgNSlbMl0pICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMikpICsNCiAgY29vcmRfZmxpcCgpKyN5bGltID0gYygyNSwgNTUpKSArDQogICNnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIpICsNCiAgI3NjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKCwgMCwgMSkpICsNCiAgbGFicyh4ID0gIkdlbmRlciIsIHkgPSAiRXN0aW1hdGVkICUgcGlnZW9ucyBmb3JhZ2luZyIsIGZpbGwgPSAiSW5kaWNhdGVkXG5leHBlY3RhdGlvbiIpICsNCiAgdGhlbWVfYncoKSArIA0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQ0KDQoNCg0KZ3A0IDwtDQogIGNhbGN1bGF0ZV9hbGxfdGhlX2RpZmZzXzIgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkaWZmX2NvbnRyYXN0LCB5ID0gcG9zdGVyaW9yX2RpZmYpKSArIA0KICAgICNzdGF0X3NsYWIoYWxwaGEgPSAwLjksIHNoYXBlID0gMjEsIGFlcyhmaWxsID0gR2VuZGVyKSkgKw0KICBzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSAzLCBzdHJva2UgPSAxLjUsDQogICAgICAgICAgICAgICBmaWxsID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMTApWzVdKSArDQogICNzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAyKSkgKw0KICBjb29yZF9mbGlwKCkrI3lsaW0gPSBjKDI1LCA1NSkpICsNCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMiwgbGluZXdpZHRoID0gMC43NSkgKw0KICAjZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygsIDAsIDEpKSArDQogIHhsYWIoIkRpZmZlcmVuY2UgY29udHJhc3QiKSArDQogIHlsYWIoIiUgcG9pbnRzIikgKw0KICB0aGVtZV9idygpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQ0KDQpgYGANCg0KJH4kDQoNCiMgUXVlc3Rpb24gMjogaXMgZXN0aW1hdGlvbiBvZiBmZWVkaW5nIHJhdGUgYWZmZWN0ZWQgYnkgYmlhcyBtYW5pcHVsYXRpb25zPw0KDQokfiQNCg0KV2UgYXNrZWQgb2JzZXJ2ZXJzIHRvIGNvdW50IHRoZSBudW1iZXIgb2YgcGVja3Mgb2YgdGhlIGdyb3VuZCB0aGF0IGEgc2VsZWN0ZWQgcGlnZW9uIG1hZGUgb3ZlciBhIDEgbWludXRlIHBlcmlvZC4gV2UgdXNlIHRoZSBudW1iZXIgb2YgcGVja3MgdGhhdCBvY2N1ciBhcyBhIG1lYXN1cmUgb2YgZmVlZGluZyByYXRlLg0KDQpXZSBmaXJzdCBlc3RpbWF0ZWQgYSBiYXNlbGluZSBwZWNrIHJhdGUgYnkgb2JzZXJ2aW5nIDM1IHBpZ2VvbnMuIFRvIHNlbGVjdCB0aGUgcGlnZW9ucyB3ZSBvYnNlcnZlZCwgd2Ugc3BsaXQgYSBzdGlsbCBpbWFnZSBvZiB0aGUgZm9yYWdpbmcgdmlkZW8gKHRha2VuIGF0IHRpbWUgemVybykgaW50byBhIDQzIHggMjEgY2VsbCBncmlkLiBGcm9tIHRoZSAxMjIgY2VsbHMgdGhhdCBjb250YWluZWQgcGlnZW9ucywgNDAgd2VyZSBjaG9zZW4gYnkgcmFuZG9tIG51bWJlciBnZW5lcmF0aW9uIChzZWUgY29kZSBjaHVuayBiZWxvdykuIEluIHRoZSBldmVudCB0aGF0IG11bHRpcGxlIHBpZ2VvbnMgd2VyZSBwcmVzZW50IGluIHRoZSBjZWxsLCB3ZSBzZWxlY3RlZCB0aGUgbW9zdCBwcm9taW5lbnQgdG8gb2JzZXJ2ZS4gRml2ZSBvYnNlcnZhdGlvbnMgd2VyZSBkaXNjYXJkZWQgLSB0aHJlZSBkdWUgdG8gb3ZlcmxhcCBvZiB0aGUgc2FtZSBwaWdlb24gYmV0d2VlbiBjZWxscyB0aGF0IHdlcmUgc2VsZWN0ZWQgYnkgdGhlIHJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yLCBhbmQgdHdvIG1vcmUgYXMgdGhlIHBpZ2VvbnMgbGVmdCB0aGUgZmllbGQgb2YgdmlldyBkdXJpbmcgdGhlIHZpZGVvIGFuZCBjb3VsZCBubyBsb25nZXIgYmUgdHJhY2tlZC4gDQoNCg0KYGBge3J9DQojIGN1cmx5IGJyYWNrZXRzIHJ1biBhbGwgbGluZXMgaW5jbHVkZWQgd2l0aGluIHRoZW0NCg0Ke3NldC5zZWVkKDEpICMgc28gdGhhdCBzYW1wbGUgcHJvZHVjZXMgYSByZXByb2R1Y2libGUgc2VxdWVuY2UgDQogIHNhbXBsZSgxOjEyMiwgNDAsIHJlcGxhY2UgPSBGQUxTRSl9DQpgYGANCg0KVGhlIHNlbGVjdGVkIHBpZ2VvbnMgZm9yIGJhc2VsaW5lIG9ic2VydmF0aW9uIGFyZSBzaG93biBpbiB0aGUgaW1hZ2UgYmVsb3cNCg0KYGBge3J9DQppbWcgPC0gcmVhZFBORygicGlnZW9uX3NlbGVjdGlvbi5wbmciKQ0KIGdyaWQucmFzdGVyKGltZykNCmBgYA0KDQoNCiR+JA0KDQojIyBFc3RpbWF0aW5nIGJhc2VsaW5lIGZlZWRpbmcgcmF0ZQ0KDQokfiQNCg0KKipMb2FkIGluIHRoZSBkYXRhKioNCg0KYGBge3J9DQoNCmJhc2VsaW5lX2RhdGEgPC0gcmVhZF9jc3YoImRhdGEvYmFzZWxpbmVfcGVja19kYXRhLmNzdiIpICU+JSANCiAgc2VsZWN0KDE6NSkgJT4lICAjIHJlbW92ZSB0aGUgY29tbWVudHMgY29sdW1uDQogIHBpdm90X2xvbmdlcihjb2xzID0gNDo1LCBuYW1lc190byA9ICJPYnNlcnZhdGlvbiIsIHZhbHVlc190byA9ICJQZWNrX3JhdGUiKSAlPiUgDQogIG11dGF0ZShJRCA9IGFzLmZhY3RvcihJRCksDQogICAgICAgICBPYnNlcnZhdGlvbiA9IHN0cl9yZW1vdmUoT2JzZXJ2YXRpb24sICJQZWNrX2NvdW50XyIpKSAlPiUgDQogIHJlbmFtZShQaWdlb25fSUQgPSBJRCkgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKFBlY2tfcmF0ZSkpDQoNCm15X2RhdGFfdGFibGUgPC0gZnVuY3Rpb24oZGYpew0KICBkYXRhdGFibGUoDQogICAgZGYsIHJvd25hbWVzPUZBTFNFLA0KICAgIGF1dG9IaWRlTmF2aWdhdGlvbiA9IFRSVUUsDQogICAgZXh0ZW5zaW9ucyA9IGMoIlNjcm9sbGVyIiwgICJCdXR0b25zIiksDQogICAgb3B0aW9ucyA9IGxpc3QoDQogICAgICBkb20gPSAnQmZydGlwJywNCiAgICAgIGRlZmVyUmVuZGVyPVRSVUUsDQogICAgICBzY3JvbGxYPVRSVUUsIHNjcm9sbFk9NDAwLA0KICAgICAgc2Nyb2xsQ29sbGFwc2U9VFJVRSwNCiAgICAgIGJ1dHRvbnMgPQ0KICAgICAgICBsaXN0KCdwYWdlTGVuZ3RoJywgJ2NvbHZpcycsICdjc3YnLCBsaXN0KA0KICAgICAgICAgIGV4dGVuZCA9ICdwZGYnLA0KICAgICAgICAgIHBhZ2VTaXplID0gJ0E0JywNCiAgICAgICAgICBvcmllbnRhdGlvbiA9ICdsYW5kc2NhcGUnLA0KICAgICAgICAgIGZpbGVuYW1lID0gJ2Jhc2VsaW5lX2RhdGFzZXQnKSksDQogICAgICBwYWdlTGVuZ3RoID0gNzgNCiAgICApDQogICkNCn0NCg0KDQpteV9kYXRhX3RhYmxlKGJhc2VsaW5lX2RhdGEpDQoNCmBgYA0KDQotIGBYYCBhbmQgYFlgIHJlcHJlc2VudCBncmlkIGNvb3JkaW5hdGVzLg0KDQotIGBQaWdlb25fSURgIGlkZW50aWZpZXMgYSBzcGVjaWZpYyBwaWdlb24NCg0KLSBgT2JzZXJ2YXRpb25gIGluZGljYXRlcyB3aGV0aGVyIHRoaXMgd2FzIHRoZSBmaXJzdCBvciBzZWNvbmQgc2NvcmluZyBmb3IgYSBzaW5nbGUgcGlnZW9uLiBXZSBzY29yZWQgZWFjaCBwaWdlb24gdHdpY2UgYXMgZGlzdGFudCBwaWdlb25zIHdlcmUgZGlmZmljdWx0IHRvIG9ic2VydmUgYW5kIHRvIGVuc3VyZSB0aGF0IHRoZSBjb3JyZWN0IHBpZ2VvbiB3YXMgdHJhY2tlZCB0aHJvdWdob3V0IHRoZSBtaW51dGUgb2Ygb2JzZXJ2YXRpb24uDQoNCi0gYFBlY2tfcmF0ZWAgaXMgdGhlIG51bWJlciBvZiB0aW1lcyB0aGUgZ3JvdW5kIHdhcyBwZWNrZWQgb3ZlciBhIG1pbnV0ZSBvZiBvYnNlcnZhdGlvbi4NCg0KJH4kDQoNCioqRml0IGEgc2ltcGxlIG1vZGVsIHRvIGVzdGltYXRlIG1lZGlhbiBwZWNrIHJhdGUqKg0KDQpgYGB7cn0NCg0KYmFzZWxpbmVfcGVja19tb2RlbF96aSA8LQ0KICBicm0oUGVja19yYXRlIH4gMSArICgxfFBpZ2Vvbl9JRCksDQogICAgICBmYW1pbHkgPSB6ZXJvX2luZmxhdGVkX25lZ2Jpbm9taWFsKCksIGRhdGEgPSBiYXNlbGluZV9kYXRhLA0KICAgICAgcHJpb3IgPSBjKCBwcmlvcihub3JtYWwoMCwgMS41KSwgY2xhc3MgPSBJbnRlcmNlcHQpLA0KICAgICAgICAgICAgICAgICBwcmlvcihleHBvbmVudGlhbCgxKSwgY2xhc3MgPSBzZCksDQogICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHNoYXBlKSwNCiAgICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gemkpKSwNCiAgICAgIGNoYWlucyA9IDQsIGNvcmVzID0gNCwgd2FybXVwID0gMjAwMCwgaXRlciA9IDYwMDAsDQogICAgICBmaWxlID0gImZpdHMvYmFzZWxpbmVfcGVja19tb2RlbCIpDQoNCiMgd3JhbmdsZSB0aGUgb3V0cHV0DQoNCmJhc2VsaW5lX3BlY2tfcHJlZGljdGlvbnMgPC0NCiAgYmFzZWxpbmVfcGVja19tb2RlbF96aSAlPiUgDQogIGFzX2RyYXdzX2RmKCkgJT4lIA0KICBtdXRhdGUoQmFzZWxpbmVfZXN0aW1hdGUgPSBleHAoYl9JbnRlcmNlcHQpLA0KICAgICAgICAgcGVja19yYXRlX3NkID0gZXhwKHNkX1BpZ2Vvbl9JRF9fSW50ZXJjZXB0KSkgJT4lIA0KICBzZWxlY3QoQmFzZWxpbmVfZXN0aW1hdGUsIHBlY2tfcmF0ZV9zZCkNCg0KYmFzZWxpbmVfZGF0YSAlPiUgDQogIGRpc3RpbmN0KFBpZ2Vvbl9JRCkgJT4lIA0KICBzdW1tYXJpc2UoYG4gcGlnZW9ucyBvYnNlcnZlZGAgPSBsZW5ndGgoUGlnZW9uX0lEKSkgJT4lDQogIGJpbmRfY29scygNCmZpdHRlZChiYXNlbGluZV9wZWNrX21vZGVsX3ppLCBzdW1tYXJ5ID0gVCwgcmVfZm9ybXVsYSA9IE5BKSAlPiUgDQogICAgICAgICAgYXNfdGliYmxlKCkgJT4lDQogICAgICAgICAgZGlzdGluY3QoRXN0aW1hdGUsIC5rZWVwX2FsbCA9IFQpICU+JSANCiAgICAgICAgICBtdXRhdGUoYWNyb3NzKDE6NCwgcm91bmQsIDIpKSAlPiUgDQogIHJlbmFtZShgQmFzZWxpbmUgbWVkaWFuIHBlY2sgcmF0ZSAvIHBlciBtaW5gID0gRXN0aW1hdGUpKSAlPiUNCiAgcGFuZGVyKCkNCg0KYGBgDQoNCiR+JA0KDQojIyBFeHBlcmltZW50YWwgZGF0YQ0KDQokfiQNCg0KIyMjIEV4cGxvcmluZyBhbGxvY2F0aW9uIHZlcnN1cyBleHBlY3RhdGlvbiAyLjAgey50YWJzZXQgLnRhYnNldC1waWxsc30NCg0KJH4kDQoNCk9uY2UgYWdhaW4sIHdlIGV4cGVjdCB0aGF0IGF0dGVudGlvbiBwYWlkIHRvIGFuZC9vciBjb21wcmVoZW5zaW9uIG9mIHRoZSBwcmltZXIgc3RhdGVtZW50IGhhcyBhIGxhcmdlIGVmZmVjdCBvbiBvYnNlcnZlcnMnIHBlcmNlcHRpb24gb2YgcGlnZW9uIGZvcmFnaW5nLiANCg0KTGV0cyBhZ2FpbiBmaXQgb3VyIHR3byBtb2RlbHM6DQoNCjEuIGEgbW9kZWwgd2l0aCBhbGxvY2F0ZWQgcHJpbWVyIChgQmlhc190cmVhdG1lbnRgKSBhcyB0aGUgcHJlZGljdG9yIHZhcmlhYmxlIA0KDQoyLiBhIG1vZGVsIHdpdGggaW5kaWNhdGVkIGh1bmdlciBleHBlY3RhdGlvbiAoYEV4cGVjdGF0aW9uYCkgYXMgdGhlIHByZWRpY3RvciB2YXJpYWJsZQ0KDQokfiQNCg0KIyMjIyBNb2RlbCAxOiBhbGxvY2F0ZWQgcHJpbWVyDQoNCmBgYHtyfQ0KDQojIEZpcnN0IGxldCdzIG1vZGVsIHRoZSBlZmZlY3Qgb2YgYmlhcyB0cmVhdG1lbnQgb24gcGVjayByYXRlDQoNCnBlY2tfbW9kZWxfdHJlYXRtZW50IDwtIA0KICBicm0oUGVja19yYXRlIH4gMCArIEJpYXNfdHJlYXRtZW50ICsgKDF8T2JzZXJ2ZXJfSUQpLA0KICAgICAgZGF0YSA9IGRhdGFfcGVjaywgZmFtaWx5ID0gbmVnYmlub21pYWwsDQogICAgICBwcmlvciA9IGMocHJpb3Iobm9ybWFsKDAsIDEuNSksIGNsYXNzID0gYiksDQogICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gc2QpKSwNCiAgICAgIGl0ZXIgPSA2MDAwLCB3YXJtdXAgPSAyMDAwLCBjaGFpbnMgPSA0LCBjb3JlcyA9IDQsDQogICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOSwgbWF4X3RyZWVkZXB0aCA9IDEyKSwNCiAgICAgIHNlZWQgPSAxLCBmaWxlID0gImZpdHMvcGVja19tb2RlbF90cmVhdG1lbnQiKQ0KDQpwZWNrX21vZGVsX3RyZWF0bWVudCA8LSBhZGRfY3JpdGVyaW9uKHBlY2tfbW9kZWxfdHJlYXRtZW50LCBjcml0ZXJpb24gPSAibG9vIiwgZmlsZSA9ICJmaXRzL3BlY2tfbW9kZWxfdHJlYXRtZW50IikNCiAgDQpwZWNrX21vZGVsX3RyZWF0bWVudA0KDQpwZWNrX21vZGVsX3RyZWF0bWVudF9nZW5kZXIgPC0gDQogIGJybShQZWNrX3JhdGUgfiAwICsgR2VuZGVyICogQmlhc190cmVhdG1lbnQgKyAoMXxPYnNlcnZlcl9JRCksDQogICAgICBkYXRhID0gZGF0YV9wZWNrLCBmYW1pbHkgPSBuZWdiaW5vbWlhbCwNCiAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMS41KSwgY2xhc3MgPSBiKSwNCiAgICAgICAgICAgICAgICBwcmlvcihleHBvbmVudGlhbCgxKSwgY2xhc3MgPSBzZCkpLA0KICAgICAgaXRlciA9IDYwMDAsIHdhcm11cCA9IDIwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwNCiAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45LCBtYXhfdHJlZWRlcHRoID0gMTIpLA0KICAgICAgc2VlZCA9IDEsIGZpbGUgPSAiZml0cy9wZWNrX21vZGVsX3RyZWF0bWVudF9nZW5kZXIiKQ0KYGBgDQoNCioqVGFibGUgUzMqKi4gVGhlIGVzdGltYXRlZCBwZWNrIHJhdGUgb2YgZm9yYWdpbmcgcGlnZW9ucywgc3BsaXQgYnkgdGhlIHByaW1lciBvYnNlcnZlcnMgd2VyZSBhbGxvY2F0ZWQuDQoNCmBgYHtyfQ0KbmV3X2RhdGEgJT4lIA0KICBiaW5kX2NvbHMoZml0dGVkKHBlY2tfbW9kZWxfdHJlYXRtZW50LCBuZXdkYXRhID0gbmV3X2RhdGEsIHN1bW1hcnkgPSBULCByZV9mb3JtdWxhID0gTkEpICU+JSANCiAgICAgICAgICAgICAgYXNfdGliYmxlKCkgJT4lIA0KICAgICAgICAgICAgICBtdXRhdGUoYWNyb3NzKDE6NCwgcm91bmQsIDIpKSkgJT4lIA0KICBsZWZ0X2pvaW4oZGF0YV9wZWNrICU+JSBncm91cF9ieShCaWFzX3RyZWF0bWVudCkgJT4lIA0KICAgICAgICAgICAgICBkaXN0aW5jdChPYnNlcnZlcl9JRCkgJT4lIHN1bW1hcmlzZShgbiBwaWdlb25zIG9ic2VydmVkYCA9IG4oKSkpICU+JSANCiAgcmVuYW1lKCJFc3RpbWF0ZWQgcGVjayByYXRlIiA9IEVzdGltYXRlLA0KICAgICAgICAgIkJpYXMgdHJlYXRtZW50IiA9IEJpYXNfdHJlYXRtZW50KSAlPiUgDQogIGJpbmRfcm93cyhmaXR0ZWQoYmFzZWxpbmVfcGVja19tb2RlbF96aSwgc3VtbWFyeSA9IFQsIHJlX2Zvcm11bGEgPSBOQSkgJT4lIA0KICAgICAgICAgICAgICBhc190aWJibGUoKSAlPiUNCiAgICAgICAgICAgICAgZGlzdGluY3QoRXN0aW1hdGUsIC5rZWVwX2FsbCA9IFQpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGFjcm9zcygxOjQsIHJvdW5kLCAyKSkgJT4lIA0KICAgICAgICAgICAgICByZW5hbWUoIkVzdGltYXRlZCBwZWNrIHJhdGUiID0gRXN0aW1hdGUpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGBCaWFzIHRyZWF0bWVudGAgPSAiQmFzZWxpbmUiKSAlPiUgDQogICAgICAgICAgICAgIGJpbmRfY29scyhiYXNlbGluZV9kYXRhICU+JSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzdGluY3QoUGlnZW9uX0lEKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcmlzZShgbiBwaWdlb25zIG9ic2VydmVkYCA9IGxlbmd0aChQaWdlb25fSUQpKSkpICU+JSANCiAgc2VsZWN0KGBCaWFzIHRyZWF0bWVudGAsIGBuIHBpZ2VvbnMgb2JzZXJ2ZWRgLCBldmVyeXRoaW5nKCkpICU+JSANCiAgcGFuZGVyKHNwbGl0LmNlbGwgPSAyMCwgc3BsaXQudGFibGUgPSBJbmYpDQoNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCiMgYWRkIHRoZSBnZW5kZXIgdGFibGUNCg0KbmV3X2RhdGFfZ2VuZGVyICU+JSANCiAgYmluZF9jb2xzKGZpdHRlZChwZWNrX21vZGVsX3RyZWF0bWVudF9nZW5kZXIsIA0KICAgICAgICAgICAgICAgbmV3ZGF0YSA9IG5ld19kYXRhX2dlbmRlciwgc3VtbWFyeSA9IFQsIHJlX2Zvcm11bGEgPSBOQSkgJT4lIA0KICAgICAgICAgIGFzX3RpYmJsZSgpICU+JSANCiAgICAgICAgICBtdXRhdGUoYWNyb3NzKDE6NCwgcm91bmQsIDIpKSkgJT4lIA0KICBsZWZ0X2pvaW4oZGF0YV9wZWNrICU+JSBncm91cF9ieShCaWFzX3RyZWF0bWVudCwgR2VuZGVyKSAlPiUgDQogICAgICAgICAgICAgICBkaXN0aW5jdChPYnNlcnZlcl9JRCkgJT4lIHN1bW1hcmlzZShgbiBwaWdlb25zIG9ic2VydmVkYCA9IG4oKSkpICU+JSANCiAgICByZW5hbWUoIkVzdGltYXRlZCBwZWNrIHJhdGUiID0gRXN0aW1hdGUsDQogICAgICAgICAiQmlhcyB0cmVhdG1lbnQiID0gQmlhc190cmVhdG1lbnQpICU+JSANCiAgYmluZF9yb3dzKGZpdHRlZChiYXNlbGluZV9wZWNrX21vZGVsX3ppLCBzdW1tYXJ5ID0gVCwgcmVfZm9ybXVsYSA9IE5BKSAlPiUgDQogICAgICAgICAgICAgIGFzX3RpYmJsZSgpICU+JQ0KICAgICAgICAgICAgICBkaXN0aW5jdChFc3RpbWF0ZSwgLmtlZXBfYWxsID0gVCkgJT4lIA0KICAgICAgICAgICAgICBtdXRhdGUoYWNyb3NzKDE6NCwgcm91bmQsIDIpKSAlPiUgDQogICAgICAgICAgICAgIHJlbmFtZSgiRXN0aW1hdGVkIHBlY2sgcmF0ZSIgPSBFc3RpbWF0ZSkgJT4lIA0KICAgICAgICAgICAgICBtdXRhdGUoYEJpYXMgdHJlYXRtZW50YCA9ICJCYXNlbGluZSIsIEdlbmRlciA9ICItIikgJT4lIA0KICAgICAgICAgICAgICBiaW5kX2NvbHMoYmFzZWxpbmVfZGF0YSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3RpbmN0KFBpZ2Vvbl9JRCkgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJpc2UoYG4gcGlnZW9ucyBvYnNlcnZlZGAgPSBsZW5ndGgoUGlnZW9uX0lEKSkpKSAlPiUgDQogIHNlbGVjdChgQmlhcyB0cmVhdG1lbnRgLCBgbiBwaWdlb25zIG9ic2VydmVkYCwgZXZlcnl0aGluZygpKSAlPiUgDQogIHBhbmRlcihzcGxpdC5jZWxsID0gMjAsIHNwbGl0LnRhYmxlID0gSW5mKQ0KYGBgDQoNCg0KIyMjIyBNb2RlbCAyOiBJbmRpY2F0ZWQgZXhwZWN0YXRpb24NCg0KYGBge3J9DQoNCiMgZml0IHRoZSBzYW1lIG1vZGVsLCBleGNlcHQgdXNpbmcgcGFydGljaXBhbnQgZXhwZWN0YXRpb24gcmF0aGVyIHRoYW4gYWxsb2NhdGVkIGJpYXMgdHJlYXRtZW50DQoNCnBlY2tfbW9kZWxfZXhwZWN0YXRpb24gPC0gYnJtKFBlY2tfcmF0ZSB+IDAgKyBFeHBlY3RhdGlvbiArICgxfE9ic2VydmVyX0lEKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YV9wZWNrLCBmYW1pbHkgPSBuZWdiaW5vbWlhbCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmlvciA9IGMocHJpb3Iobm9ybWFsKDAsIDEuNSksIGNsYXNzID0gYiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yKGV4cG9uZW50aWFsKDEpLCBjbGFzcyA9IHNkKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlciA9IDYwMDAsIHdhcm11cCA9IDIwMDAsIGNoYWlucyA9IDQsIGNvcmVzID0gNCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gbGlzdChhZGFwdF9kZWx0YSA9IDAuOTUsIG1heF90cmVlZGVwdGggPSAxMiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZCA9IDEsIGZpbGUgPSAiZml0cy9wZWNrX21vZGVsX2V4cGVjdGF0aW9uIikNCg0KcGVja19tb2RlbF9leHBlY3RhdGlvbiA8LSBhZGRfY3JpdGVyaW9uKHBlY2tfbW9kZWxfZXhwZWN0YXRpb24sIGNyaXRlcmlvbiA9ICJsb28iLCBmaWxlID0gImZpdHMvcGVja19tb2RlbF9leHBlY3RhdGlvbiIpDQoNCg0KcGVja19tb2RlbF9leHBlY3RhdGlvbg0KI2xvb19jb21wYXJlKHBlY2tfbW9kZWxfdHJlYXRtZW50LCBwZWNrX21vZGVsX2V4cGVjdGF0aW9uKQ0KDQpwZWNrX21vZGVsX2V4cGVjdGF0aW9uX2dlbmRlciA8LSBicm0oUGVja19yYXRlIH4gMCArIEdlbmRlciAqIEV4cGVjdGF0aW9uICsgKDF8T2JzZXJ2ZXJfSUQpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhX3BlY2ssIGZhbWlseSA9IG5lZ2Jpbm9taWFsLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW9yID0gYyhwcmlvcihub3JtYWwoMCwgMS41KSwgY2xhc3MgPSBiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3IoZXhwb25lbnRpYWwoMSksIGNsYXNzID0gc2QpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVyID0gNjAwMCwgd2FybXVwID0gMjAwMCwgY2hhaW5zID0gNCwgY29yZXMgPSA0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45NSwgbWF4X3RyZWVkZXB0aCA9IDEyKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkID0gMSwgZmlsZSA9ICJmaXRzL3BlY2tfbW9kZWxfZXhwZWN0YXRpb25fZ2VuZGVyIikNCmBgYA0KDQoqKlRhYmxlIFM0KiouIFRoZSBlc3RpbWF0ZWQgcGVjayByYXRlIG9mIGZvcmFnaW5nIHBpZ2VvbnMsIHNwbGl0IGJ5IHRoZSBpbmRpY2F0ZWQgZXhwZWN0YXRpb24gb2YgdGhlIG9ic2VydmVycy4NCg0KYGBge3J9DQoNCm5ld19kYXRhXzIgJT4lIA0KICBiaW5kX2NvbHMoZml0dGVkKHBlY2tfbW9kZWxfZXhwZWN0YXRpb24sIG5ld2RhdGEgPSBuZXdfZGF0YV8yLCBzdW1tYXJ5ID0gVCwgcmVfZm9ybXVsYSA9IE5BKSAlPiUgDQogICAgICAgICAgICAgIGFzX3RpYmJsZSgpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGFjcm9zcygxOjQsIHJvdW5kLCAyKSkpICU+JSANCiAgbGVmdF9qb2luKGRhdGFfcGVjayAlPiUgZ3JvdXBfYnkoRXhwZWN0YXRpb24pICU+JSANCiAgICAgICAgICAgICAgZGlzdGluY3QoT2JzZXJ2ZXJfSUQpICU+JSBzdW1tYXJpc2UoYG4gcGlnZW9ucyBvYnNlcnZlZGAgPSBuKCkpKSAlPiUgDQogIHJlbmFtZSgiRXN0aW1hdGVkIHBlY2sgcmF0ZSIgPSBFc3RpbWF0ZSwNCiAgICAgICAgICJJbmRpY2F0ZWQgZXhwZWN0YXRpb24iID0gRXhwZWN0YXRpb24pICU+JSANCiAgYmluZF9yb3dzKGZpdHRlZChiYXNlbGluZV9wZWNrX21vZGVsX3ppLCBzdW1tYXJ5ID0gVCwgcmVfZm9ybXVsYSA9IE5BKSAlPiUgDQogICAgICAgICAgICAgIGFzX3RpYmJsZSgpICU+JQ0KICAgICAgICAgICAgICBkaXN0aW5jdChFc3RpbWF0ZSwgLmtlZXBfYWxsID0gVCkgJT4lIA0KICAgICAgICAgICAgICBtdXRhdGUoYWNyb3NzKDE6NCwgcm91bmQsIDIpKSAlPiUgDQogICAgICAgICAgICAgIHJlbmFtZSgiRXN0aW1hdGVkIHBlY2sgcmF0ZSIgPSBFc3RpbWF0ZSkgJT4lIA0KICAgICAgICAgICAgICBtdXRhdGUoYEluZGljYXRlZCBleHBlY3RhdGlvbmAgPSAiQmFzZWxpbmUiKSAlPiUgDQogICAgICAgICAgICAgIGJpbmRfY29scyhiYXNlbGluZV9kYXRhICU+JSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzdGluY3QoUGlnZW9uX0lEKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcmlzZShgbiBwaWdlb25zIG9ic2VydmVkYCA9IGxlbmd0aChQaWdlb25fSUQpKSkpICU+JSANCiAgc2VsZWN0KGBJbmRpY2F0ZWQgZXhwZWN0YXRpb25gLCBgbiBwaWdlb25zIG9ic2VydmVkYCwgZXZlcnl0aGluZygpKSAlPiUgDQogIHBhbmRlcihzcGxpdC5jZWxsID0gMjAsIHNwbGl0LnRhYmxlID0gSW5mKQ0KDQpgYGANCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQoNCiMgYWRkIHRoZSBnZW5kZXIgdGFibGUNCg0KbmV3X2RhdGFfZ2VuZGVyXzIgJT4lIA0KICBiaW5kX2NvbHMoZml0dGVkKHBlY2tfbW9kZWxfZXhwZWN0YXRpb25fZ2VuZGVyLCANCiAgICAgICAgICAgICAgIG5ld2RhdGEgPSBuZXdfZGF0YV9nZW5kZXJfMiwgc3VtbWFyeSA9IFQsIHJlX2Zvcm11bGEgPSBOQSkgJT4lIA0KICAgICAgICAgIGFzX3RpYmJsZSgpICU+JSANCiAgICAgICAgICBtdXRhdGUoYWNyb3NzKDE6NCwgcm91bmQsIDIpKSkgJT4lIA0KICBsZWZ0X2pvaW4oZGF0YV9wZWNrICU+JSBncm91cF9ieShFeHBlY3RhdGlvbiwgR2VuZGVyKSAlPiUgDQogICAgICAgICAgICAgICBkaXN0aW5jdChPYnNlcnZlcl9JRCkgJT4lIHN1bW1hcmlzZShgbiBwaWdlb25zIG9ic2VydmVkYCA9IG4oKSkpICU+JSANCiAgICByZW5hbWUoIkVzdGltYXRlZCBwZWNrIHJhdGUiID0gRXN0aW1hdGUsDQogICAgICAgICAiSW5kaWNhdGVkIGV4cGVjdGF0aW9uIiA9IEV4cGVjdGF0aW9uKSAlPiUgDQogIGJpbmRfcm93cyhmaXR0ZWQoYmFzZWxpbmVfcGVja19tb2RlbF96aSwgc3VtbWFyeSA9IFQsIHJlX2Zvcm11bGEgPSBOQSkgJT4lIA0KICAgICAgICAgICAgICBhc190aWJibGUoKSAlPiUNCiAgICAgICAgICAgICAgZGlzdGluY3QoRXN0aW1hdGUsIC5rZWVwX2FsbCA9IFQpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGFjcm9zcygxOjQsIHJvdW5kLCAyKSkgJT4lIA0KICAgICAgICAgICAgICByZW5hbWUoIkVzdGltYXRlZCBwZWNrIHJhdGUiID0gRXN0aW1hdGUpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGBJbmRpY2F0ZWQgZXhwZWN0YXRpb25gID0gIkJhc2VsaW5lIiwgR2VuZGVyID0gIi0iKSAlPiUgDQogICAgICAgICAgICAgIGJpbmRfY29scyhiYXNlbGluZV9kYXRhICU+JSANCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzdGluY3QoUGlnZW9uX0lEKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcmlzZShgbiBwaWdlb25zIG9ic2VydmVkYCA9IGxlbmd0aChQaWdlb25fSUQpKSkpICU+JSANCiAgc2VsZWN0KGBJbmRpY2F0ZWQgZXhwZWN0YXRpb25gLCBgbiBwaWdlb25zIG9ic2VydmVkYCwgZXZlcnl0aGluZygpKSAlPiUgDQogIHBhbmRlcihzcGxpdC5jZWxsID0gMjAsIHNwbGl0LnRhYmxlID0gSW5mKQ0KYGBgDQoNCg0KJH4kDQoNCiMjIyBCdWlsZCBGaWd1cmUgMWUtaA0KDQokfiQNCg0KKipHZXQgcG9zdGVyaW9yIG1lYW5zIGFuZCBkaWZmZXJlbmNlIGNvbnRyYXN0cyoqDQoNCmBgYHtyfQ0KDQojIHRyZWF0bWVudCBtb2RlbA0KDQpwZWNrX2RyYXdzX3RyZWF0bWVudCA8LQ0KICBhc19kcmF3c19kZihwZWNrX21vZGVsX3RyZWF0bWVudCkgJT4lIA0KICBtdXRhdGUoSHVuZ3J5ID0gZXhwKGJfQmlhc190cmVhdG1lbnRIdW5ncnkpLA0KICAgICAgICAgU2F0aWF0ZWQgPSBleHAoYl9CaWFzX3RyZWF0bWVudFNhdGlhdGVkKSwNCiAgICAgICAgIGRpZmZfY29udHJhc3QgPSAoSHVuZ3J5IC0gU2F0aWF0ZWQpKSAlPiUgDQogIHNlbGVjdChIdW5ncnksIFNhdGlhdGVkLCBkaWZmX2NvbnRyYXN0KSAlPiUNCiAgYmluZF9jb2xzKGJhc2VsaW5lX3BlY2tfcHJlZGljdGlvbnMgJT4lIHNlbGVjdChCYXNlbGluZV9lc3RpbWF0ZSkpICU+JSANCiAgcGl2b3RfbG9uZ2VyKG5hbWVzX3RvID0gIlRyZWF0bWVudCIsIHZhbHVlc190byA9ICJQb3N0ZXJpb3JfZXN0aW1hdGUiLCBjb2xzID0gMTozKSAlPiUgDQogIG11dGF0ZShQcmVkaWN0b3IgPSAiQWxsb2NhdGVkIHByaW1lciIpDQoNCg0KcDYgPC0gDQogICAgcGVja19kcmF3c190cmVhdG1lbnQgJT4lIA0KICAgIGZpbHRlcihUcmVhdG1lbnQgIT0gImRpZmZfY29udHJhc3QiKSAlPiUgDQogICAgZ2dwbG90KGFlcyh4ID0gVHJlYXRtZW50LCB5ID0gUG9zdGVyaW9yX2VzdGltYXRlKSkgKw0KICAgIHN0YXRfc2xhYihhZXMoeSA9IEJhc2VsaW5lX2VzdGltYXRlKSwNCiAgICAgICAgICAgICAgbGluZXR5cGUgPSAyLCBsaW5ld2lkdGggPSAwLjgsIHNsYWJfZmlsbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIpICsNCiAgICBzdGF0X2hhbGZleWUoYWVzKGZpbGwgPSBUcmVhdG1lbnQpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwNCiAgICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVkaWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSA0LCBzdHJva2UgPSAxLjUpICsNCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAyKSkgKw0KICAgIGNvb3JkX2ZsaXAoeWxpbSA9IGMoMCwgMjApKSArDQogICAgI2dlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMikgKw0KICAgICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygsIDAsIDEpKSArDQogICAgeGxhYigiQWxsb2NhdGVkIHByaW1lciIpICsNCiAgICB5bGFiKCJFc3RpbWF0ZWQgcGVja3MgcGVyIG1pbiIpICsNCiAgICB0aGVtZV9idygpICsgDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpKQ0KDQpwNyA8LQ0KICBwZWNrX2RyYXdzX3RyZWF0bWVudCAlPiUgDQogIGZpbHRlcihUcmVhdG1lbnQgPT0gImRpZmZfY29udHJhc3QiKSAlPiUgDQogIGdncGxvdChhZXMoeSA9IFBvc3Rlcmlvcl9lc3RpbWF0ZSkpICsgDQogICBzdGF0X2hhbGZleWUoYWVzKGZpbGwgPSBUcmVhdG1lbnQpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwNCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lZGlhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLA0KICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSwgc2NhbGUgPTAuNSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiKVs0XSkgKw0KICBjb29yZF9mbGlwKHlsaW0gPSBjKC01LCAxMikpICsNCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyLCBsaW5ld2lkdGggPSAwLjc1KSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygsIDAsIDEpKSArDQogIHhsYWIoTlVMTCkgKw0KICB5bGFiKCJIdW5ncnkgLSBTYXRpYXRlZCBkaWZmZXJlbmNlXG5jb250cmFzdCAocGVja3MgcGVyIG1pbikiKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGlja3MueT1lbGVtZW50X2JsYW5rKCksDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkNCg0KIyBleHBlY3RhdGlvbiBtb2RlbA0KDQpwZWNrX2RyYXdzX2V4cGVjdGF0aW9uIDwtDQogIGFzX2RyYXdzX2RmKHBlY2tfbW9kZWxfZXhwZWN0YXRpb24pICU+JSANCiAgbXV0YXRlKEh1bmdyeSA9IGV4cChiX0V4cGVjdGF0aW9uSHVuZ3J5KSwNCiAgICAgICAgIFNhdGlhdGVkID0gZXhwKGJfRXhwZWN0YXRpb25TYXRpYXRlZCksDQogICAgICAgICBkaWZmX2NvbnRyYXN0ID0gKEh1bmdyeSAtIFNhdGlhdGVkKSkgJT4lIA0KICBzZWxlY3QoSHVuZ3J5LCBTYXRpYXRlZCwgZGlmZl9jb250cmFzdCkgJT4lIA0KICBiaW5kX2NvbHMoYmFzZWxpbmVfcGVja19wcmVkaWN0aW9ucyAlPiUgc2VsZWN0KEJhc2VsaW5lX2VzdGltYXRlKSkgJT4lIA0KICBwaXZvdF9sb25nZXIobmFtZXNfdG8gPSAiVHJlYXRtZW50IiwgdmFsdWVzX3RvID0gIlBvc3Rlcmlvcl9lc3RpbWF0ZSIsIGNvbHMgPSAxOjMpICU+JSANCiAgbXV0YXRlKFByZWRpY3RvciA9ICJBbGxvY2F0ZWQgcHJpbWVyIikNCg0KcDggPC0NCiAgcGVja19kcmF3c19leHBlY3RhdGlvbiAlPiUgDQogIGZpbHRlcihUcmVhdG1lbnQgIT0gImRpZmZfY29udHJhc3QiKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IFRyZWF0bWVudCwgeSA9IFBvc3Rlcmlvcl9lc3RpbWF0ZSkpICsgDQogIHN0YXRfc2xhYihhZXMoeSA9IEJhc2VsaW5lX2VzdGltYXRlKSwNCiAgICAgICAgICAgICAgbGluZXR5cGUgPSAyLCBsaW5ld2lkdGggPSAwLjgsIHNsYWJfZmlsbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIpICsNCiAgICBzdGF0X2hhbGZleWUoYWVzKGZpbGwgPSBUcmVhdG1lbnQpLCAud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwNCiAgICAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lZGlhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLA0KICAgICAgICAgICAgICAgc2hhcGUgPSAyMSwgcG9pbnRfc2l6ZSA9IDQsIHN0cm9rZSA9IDEuNSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAyKSkgKw0KICBjb29yZF9mbGlwKHlsaW0gPSBjKDAsIDIwKSkgKw0KICAjZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygsIDAsIDEpKSArDQogIHhsYWIoIkluZGljYXRlZCBleHBlY3RhdGlvbiIpICsNCiAgeWxhYigiRXN0aW1hdGVkIHBlY2tzIHBlciBtaW4iKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpDQoNCnA5IDwtDQogIHBlY2tfZHJhd3NfZXhwZWN0YXRpb24gJT4lIA0KICBmaWx0ZXIoVHJlYXRtZW50ID09ICJkaWZmX2NvbnRyYXN0IikgJT4lIA0KICBnZ3Bsb3QoYWVzKHkgPSBQb3N0ZXJpb3JfZXN0aW1hdGUpKSArIA0KICAgc3RhdF9oYWxmZXllKGFlcyhmaWxsID0gVHJlYXRtZW50KSwgLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSA0LCBzdHJva2UgPSAxLjUsIHNjYWxlID0wLjUpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIilbNF0pICsNCiAgY29vcmRfZmxpcCh5bGltID0gYygtNSwgMTIpKSArDQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMiwgbGluZXdpZHRoID0gMC43NSkgKw0KICAjc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoLCAwLCAxKSkgKw0KICB4bGFiKE5VTEwpICsNCiAgeWxhYigiSHVuZ3J5IC0gU2F0aWF0ZWQgZGlmZmVyZW5jZVxuY29udHJhc3QgKHBlY2tzIHBlciBtaW4pIikgKw0KICB0aGVtZV9idygpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpDQpgYGANCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQojIHdpdGggZ2VuZGVyDQoNCmdlbmRlcl90cmVhdG1lbnRfZHJhd3NfMiA8LQ0KICBmaXR0ZWQocGVja19tb2RlbF90cmVhdG1lbnRfZ2VuZGVyLCANCiAgICAgICAgIG5ld2RhdGEgPSBuZXdfZGF0YV9nZW5kZXIsIHN1bW1hcnkgPSBGLCByZV9mb3JtdWxhID0gTkEpICU+JSANCiAgYXNfdGliYmxlKCkgJT4lIA0KICByZW5hbWUoSHVuZ3J5X1dvbWVuID0gVjEsIEh1bmdyeV9NZW4gPSBWMiwgU2F0aWF0ZWRfV29tZW4gPSBWMywgU2F0aWF0ZWRfTWVuID0gVjQpICU+JSANCiAgYmluZF9jb2xzKGJhc2VsaW5lX3BlY2tfcHJlZGljdGlvbnMgJT4lIHNlbGVjdChCYXNlbGluZV9lc3RpbWF0ZSkpICU+JSANCiAgcGl2b3RfbG9uZ2VyKG5hbWVzX3RvID0gIkdyb3VwIiwgdmFsdWVzX3RvID0gIlBvc3Rlcmlvcl9lc3RpbWF0ZSIsIGNvbHMgPSAxOjQpICU+JSANCiAgc2VwYXJhdGUoc2VwID0gIl8iLCBjb2wgPSBHcm91cCwgaW50byA9IGMoIlRyZWF0bWVudCIsICJHZW5kZXIiKSkNCiAgDQpjYWxjdWxhdGVfYWxsX3RoZV9kaWZmc18zIDwtDQogIGZpdHRlZChwZWNrX21vZGVsX3RyZWF0bWVudF9nZW5kZXIsIA0KICAgICAgICAgbmV3ZGF0YSA9IG5ld19kYXRhX2dlbmRlciwgc3VtbWFyeSA9IEYsIHJlX2Zvcm11bGEgPSBOQSkgJT4lIA0KICBhc190aWJibGUoKSAlPiUgDQogIHJlbmFtZShIdW5ncnlfV29tZW4gPSBWMSwgSHVuZ3J5X01lbiA9IFYyLCBTYXRpYXRlZF9Xb21lbiA9IFYzLCBTYXRpYXRlZF9NZW4gPSBWNCkgJT4lIA0KICBtdXRhdGUoV29tZW5faF9zX2RpZmYgPSBIdW5ncnlfV29tZW4gLSBTYXRpYXRlZF9Xb21lbiwNCiAgICAgICAgIE1lbl9oX3NfZGlmZiA9IEh1bmdyeV9NZW4gLSBTYXRpYXRlZF9NZW4sDQogICAgICAgICBkaWZmX2RpZmYgPSBXb21lbl9oX3NfZGlmZiAtIE1lbl9oX3NfZGlmZikgJT4lIA0KICBzZWxlY3QoY29udGFpbnMoImRpZmYiKSkgJT4lDQogIHJlbmFtZShgSC1TICh3b21lbilgID0gV29tZW5faF9zX2RpZmYsDQogICAgICAgICBgSC1TIChtZW4pYCA9IE1lbl9oX3NfZGlmZiwNCiAgICAgICAgIGBJbnRlcmFjdGlvbmAgPSBkaWZmX2RpZmYpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAxOjMsIG5hbWVzX3RvID0gImRpZmZfY29udHJhc3QiLCB2YWx1ZXNfdG8gPSAicG9zdGVyaW9yX2RpZmYiKQ0KDQpncDUgPC0gDQogIGdlbmRlcl90cmVhdG1lbnRfZHJhd3NfMiAlPiUgDQogIGdncGxvdChhZXMoeCA9IEdlbmRlciwgeSA9IFBvc3Rlcmlvcl9lc3RpbWF0ZSkpICsgDQogICAgc3RhdF9zbGFiKGFscGhhID0gMC44LCBzaGFwZSA9IDIxLCBhZXMoZmlsbCA9IFRyZWF0bWVudCkpICsNCiAgc3RhdF9zbGFiKGFlcyh5ID0gQmFzZWxpbmVfZXN0aW1hdGUpLA0KICAgICAgICAgICAgICBsaW5ldHlwZSA9IDIsIGxpbmV3aWR0aCA9IDAuOCwgc2xhYl9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIikgKw0KICAjc3RhdF9oYWxmZXllKC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMC45LA0KICAgIyAgICAgICAgICAgIHBvaW50X2ludGVydmFsID0gIm1lZGlhbl9xaSIsIHBvaW50X2ZpbGwgPSAid2hpdGUiLA0KICAgIyAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSA0LCBzdHJva2UgPSAxLjUsDQogICAjICAgICAgICAgICAgZmlsbCA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDUpWzJdKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMobWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMTApWzRdLCBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAxMClbNl0pKSArDQogIGNvb3JkX2ZsaXAoKSsjeWxpbSA9IGMoMjUsIDU1KSkgKw0KICAjZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gYygsIDAsIDEpKSArDQogIGxhYnMoeCA9ICJHZW5kZXIiLCB5ID0gIkVzdGltYXRlZCBwZWNrcyBwZXIgbWluIiwgZmlsbCA9ICJBbGxvY2F0ZWRcblByaW1lciIpICsNCiAgdGhlbWVfYncoKSArIA0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCksDQogICAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQ0KDQoNCg0KZ3A2IDwtDQogIGNhbGN1bGF0ZV9hbGxfdGhlX2RpZmZzXzMgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBkaWZmX2NvbnRyYXN0LCB5ID0gcG9zdGVyaW9yX2RpZmYpKSArIA0KICAgICNzdGF0X3NsYWIoYWxwaGEgPSAwLjksIHNoYXBlID0gMjEsIGFlcyhmaWxsID0gR2VuZGVyKSkgKw0KICBzdGF0X2hhbGZleWUoLndpZHRoID0gYygwLjY2LCAwLjk1KSwgYWxwaGEgPSAwLjksDQogICAgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICAgICAgICAgICAgIHNoYXBlID0gMjEsIHBvaW50X3NpemUgPSAzLCBzdHJva2UgPSAxLjUsDQogICAgICAgICAgICAgICBmaWxsID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMTApWzVdKSArDQogICNzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAyKSkgKw0KICBjb29yZF9mbGlwKCkrI3lsaW0gPSBjKDI1LCA1NSkpICsNCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMiwgbGluZXdpZHRoID0gMC43NSkgKw0KICAjZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMCwgbGluZXR5cGUgPSAyKSArDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0xMCwgMTUpKSArDQogIHhsYWIoIkRpZmZlcmVuY2UgY29udHJhc3QiKSArDQogIHlsYWIoIlBlY2tzIHBlciBtaW4iKSArDQogIHRoZW1lX2J3KCkgKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpDQoNCg0KIyBleHBlY3RhdGlvbiBtb2RlbA0KDQpnZW5kZXJfZXhwZWN0YXRpb25fZHJhd3NfMiA8LQ0KICBmaXR0ZWQocGVja19tb2RlbF9leHBlY3RhdGlvbl9nZW5kZXIsIA0KICAgICAgICAgbmV3ZGF0YSA9IG5ld19kYXRhX2dlbmRlcl8yLCBzdW1tYXJ5ID0gRiwgcmVfZm9ybXVsYSA9IE5BKSAlPiUgDQogIGFzX3RpYmJsZSgpICU+JSANCiAgcmVuYW1lKEh1bmdyeV9Xb21lbiA9IFYxLCBIdW5ncnlfTWVuID0gVjIsIFNhdGlhdGVkX1dvbWVuID0gVjMsIFNhdGlhdGVkX01lbiA9IFY0KSAlPiUgDQogIGJpbmRfY29scyhiYXNlbGluZV9wZWNrX3ByZWRpY3Rpb25zICU+JSBzZWxlY3QoQmFzZWxpbmVfZXN0aW1hdGUpKSAlPiUgDQogIHBpdm90X2xvbmdlcihuYW1lc190byA9ICJHcm91cCIsIHZhbHVlc190byA9ICJQb3N0ZXJpb3JfZXN0aW1hdGUiLCBjb2xzID0gMTo0KSAlPiUgDQogIHNlcGFyYXRlKHNlcCA9ICJfIiwgY29sID0gR3JvdXAsIGludG8gPSBjKCJUcmVhdG1lbnQiLCAiR2VuZGVyIikpDQogIA0KY2FsY3VsYXRlX2FsbF90aGVfZGlmZnNfNCA8LQ0KICBmaXR0ZWQocGVja19tb2RlbF9leHBlY3RhdGlvbl9nZW5kZXIsIA0KICAgICAgICAgbmV3ZGF0YSA9IG5ld19kYXRhX2dlbmRlcl8yLCBzdW1tYXJ5ID0gRiwgcmVfZm9ybXVsYSA9IE5BKSAlPiUgDQogIGFzX3RpYmJsZSgpICU+JSANCiAgcmVuYW1lKEh1bmdyeV9Xb21lbiA9IFYxLCBIdW5ncnlfTWVuID0gVjIsIFNhdGlhdGVkX1dvbWVuID0gVjMsIFNhdGlhdGVkX01lbiA9IFY0KSAlPiUgDQogIG11dGF0ZShXb21lbl9oX3NfZGlmZiA9IEh1bmdyeV9Xb21lbiAtIFNhdGlhdGVkX1dvbWVuLA0KICAgICAgICAgTWVuX2hfc19kaWZmID0gSHVuZ3J5X01lbiAtIFNhdGlhdGVkX01lbiwNCiAgICAgICAgIGRpZmZfZGlmZiA9IFdvbWVuX2hfc19kaWZmIC0gTWVuX2hfc19kaWZmKSAlPiUgDQogIHNlbGVjdChjb250YWlucygiZGlmZiIpKSAlPiUNCiAgcmVuYW1lKGBILVMgKHdvbWVuKWAgPSBXb21lbl9oX3NfZGlmZiwNCiAgICAgICAgIGBILVMgKG1lbilgID0gTWVuX2hfc19kaWZmLA0KICAgICAgICAgYEludGVyYWN0aW9uYCA9IGRpZmZfZGlmZikgJT4lIA0KICBwaXZvdF9sb25nZXIoY29scyA9IDE6MywgbmFtZXNfdG8gPSAiZGlmZl9jb250cmFzdCIsIHZhbHVlc190byA9ICJwb3N0ZXJpb3JfZGlmZiIpDQoNCmdwNyA8LSANCiAgZ2VuZGVyX2V4cGVjdGF0aW9uX2RyYXdzXzIgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBHZW5kZXIsIHkgPSBQb3N0ZXJpb3JfZXN0aW1hdGUpKSArIA0KICAgIHN0YXRfc2xhYihhbHBoYSA9IDAuOSwgc2hhcGUgPSAyMSwgYWVzKGZpbGwgPSBUcmVhdG1lbnQpKSArDQogIHN0YXRfc2xhYihhZXMoeSA9IEJhc2VsaW5lX2VzdGltYXRlKSwNCiAgICAgICAgICAgICAgbGluZXR5cGUgPSAyLCBsaW5ld2lkdGggPSAwLjgsIHNsYWJfZmlsbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIpICsNCiAgI3N0YXRfaGFsZmV5ZSgud2lkdGggPSBjKDAuNjYsIDAuOTUpLCBhbHBoYSA9IDAuOSwNCiAgICMgICAgICAgICAgICBwb2ludF9pbnRlcnZhbCA9ICJtZWRpYW5fcWkiLCBwb2ludF9maWxsID0gIndoaXRlIiwNCiAgICMgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gNCwgc3Ryb2tlID0gMS41LA0KICAgIyAgICAgICAgICAgIGZpbGwgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCA1KVsyXSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBtZXQuYnJld2VyKCJIaXJvc2hpZ2UiLCAyKSkgKw0KICBjb29yZF9mbGlwKCkrI3lsaW0gPSBjKDI1LCA1NSkpICsNCiAgI2dlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMikgKw0KICAjc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoLCAwLCAxKSkgKw0KICBsYWJzKHggPSAiR2VuZGVyIiwgeSA9ICJFc3RpbWF0ZWQgcGVja3MgcGVyIG1pbiIsIGZpbGwgPSAiSW5kaWNhdGVkXG5leHBlY3RhdGlvbiIpICsNCiAgdGhlbWVfYncoKSArIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkNCg0KDQoNCmdwOCA8LQ0KICBjYWxjdWxhdGVfYWxsX3RoZV9kaWZmc180ICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gZGlmZl9jb250cmFzdCwgeSA9IHBvc3Rlcmlvcl9kaWZmKSkgKyANCiAgICAjc3RhdF9zbGFiKGFscGhhID0gMC45LCBzaGFwZSA9IDIxLCBhZXMoZmlsbCA9IEdlbmRlcikpICsNCiAgc3RhdF9oYWxmZXllKC53aWR0aCA9IGMoMC42NiwgMC45NSksIGFscGhhID0gMC45LA0KICAgICAgICAgICAgICAgcG9pbnRfaW50ZXJ2YWwgPSAibWVkaWFuX3FpIiwgcG9pbnRfZmlsbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgICBzaGFwZSA9IDIxLCBwb2ludF9zaXplID0gMywgc3Ryb2tlID0gMS41LA0KICAgICAgICAgICAgICAgZmlsbCA9IG1ldC5icmV3ZXIoIkhpcm9zaGlnZSIsIDEwKVs1XSkgKw0KICAjc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbWV0LmJyZXdlcigiSGlyb3NoaWdlIiwgMikpICsNCiAgY29vcmRfZmxpcCgpKyN5bGltID0gYygyNSwgNTUpKSArDQogICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9IDIsIGxpbmV3aWR0aCA9IDAuNzUpICsNCiAgI2dlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gMikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtMTAsIDE1KSkgKw0KICB4bGFiKCJEaWZmZXJlbmNlIGNvbnRyYXN0IikgKw0KICB5bGFiKCJQZWNrcyBwZXIgbWluIikgKw0KICB0aGVtZV9idygpICsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQ0KYGBgDQoNCg0KJH4kDQoNCiMjIyBGaW5kIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gYmFzZWxpbmUgYW5kIG9ic2VydmVyIGVzdGltYXRlcw0KDQoqKlRhYmxlIFM1KiouIFRoZSBkZWdyZWUgdG8gd2hpY2ggZWFjaCBncm91cCBvZiBvYnNlcnZlcidzIG92ZXJlc3RpbWF0ZXMgZmVlZGluZyByYXRlIChudW1iZXIgb2YgZ3JvdW5kIHBlY2tzIHBlciBtaW51dGUpDQoNCmBgYHtyfQ0KYmFzZWxpbmVfcGVja19wcmVkaWN0aW9ucyAlPiUgc2VsZWN0KEJhc2VsaW5lX2VzdGltYXRlKSAlPiUgIGJpbmRfY29scygNCiAgDQogIGFzX2RyYXdzX2RmKHBlY2tfbW9kZWxfdHJlYXRtZW50KSAlPiUgDQogICAgbXV0YXRlKEh1bmdyeSA9IGV4cChiX0JpYXNfdHJlYXRtZW50SHVuZ3J5KSwNCiAgICAgICAgICAgU2F0aWF0ZWQgPSBleHAoYl9CaWFzX3RyZWF0bWVudFNhdGlhdGVkKSkgJT4lIA0KICAgIHNlbGVjdChIdW5ncnksIFNhdGlhdGVkKSkgJT4lIA0KICBtdXRhdGUoYEJpYXMgdHJlYXRtZW50IFNhdGlhdGVkIC8gQmFzZWxpbmVgID0gU2F0aWF0ZWQgLyBCYXNlbGluZV9lc3RpbWF0ZSwNCiAgICAgICAgIGBCaWFzIHRyZWF0bWVudCBIdW5ncnkgLyBCYXNlbGluZWAgPSBIdW5ncnkgLyBCYXNlbGluZV9lc3RpbWF0ZSkgJT4lIA0KICBzZWxlY3QoY29udGFpbnMoIkJpYXMiKSkgJT4lIA0KICBwaXZvdF9sb25nZXIoY29scyA9IGV2ZXJ5dGhpbmcoKSwgdmFsdWVzX3RvID0gImVzdGltYXRlIiwgbmFtZXNfdG8gPSAiU3RhdCIpICU+JSANCiAgZ3JvdXBfYnkoU3RhdCkgJT4lIA0KICBzdW1tYXJpc2VfZHJhd3MoIm1lZGlhbiIsICJzZCIsIH5xdWFudGlsZSgueCwgcHJvYnMgPSBjKDAuMDI1LCAwLjk3NSksIG5hLnJtID0gVFJVRSksIC5jb3JlcyA9IDQpICU+JSANCiAgc2VsZWN0KC12YXJpYWJsZSkgJT4lIA0KICANCiAgYmluZF9yb3dzKA0KICAgIA0KICAgIGJhc2VsaW5lX3BlY2tfcHJlZGljdGlvbnMgJT4lIHNlbGVjdChCYXNlbGluZV9lc3RpbWF0ZSkgJT4lICBiaW5kX2NvbHMoDQogICAgICANCiAgICAgIGFzX2RyYXdzX2RmKHBlY2tfbW9kZWxfZXhwZWN0YXRpb24pICU+JSANCiAgICAgICAgbXV0YXRlKEh1bmdyeSA9IGV4cChiX0V4cGVjdGF0aW9uSHVuZ3J5KSwNCiAgICAgICAgICAgICAgIFNhdGlhdGVkID0gZXhwKGJfRXhwZWN0YXRpb25TYXRpYXRlZCkpICU+JSANCiAgICAgICAgc2VsZWN0KEh1bmdyeSwgU2F0aWF0ZWQpKSAlPiUgDQogICAgICBtdXRhdGUoYEV4cGVjdGF0aW9uIFNhdGlhdGVkIC8gQmFzZWxpbmVgID0gU2F0aWF0ZWQgLyBCYXNlbGluZV9lc3RpbWF0ZSwNCiAgICAgICAgICAgICBgRXhwZWN0YXRpb24gSHVuZ3J5IC8gQmFzZWxpbmVgID0gSHVuZ3J5IC8gQmFzZWxpbmVfZXN0aW1hdGUpICU+JSANCiAgICAgIHNlbGVjdChjb250YWlucygiRXhwZWN0YXRpb24iKSkgJT4lIA0KICAgICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBldmVyeXRoaW5nKCksIHZhbHVlc190byA9ICJlc3RpbWF0ZSIsIG5hbWVzX3RvID0gIlN0YXQiKSAlPiUgDQogICAgICBncm91cF9ieShTdGF0KSAlPiUgDQogICAgICBzdW1tYXJpc2VfZHJhd3MoIm1lZGlhbiIsICJzZCIsIH5xdWFudGlsZSgueCwgcHJvYnMgPSBjKDAuMDI1LCAwLjk3NSksIG5hLnJtID0gVFJVRSksIC5jb3JlcyA9IDQpICU+JSANCiAgICAgIHNlbGVjdCgtdmFyaWFibGUpDQogICkgJT4lIA0KICBwYW5kZXIoKQ0KYGBgDQoNCg0KIyBGaWd1cmUgMQ0KDQpPcHRpb24gMQ0KDQpgYGB7ciwgZmlnLmhlaWdodD0xMiwgd2lkdGggPSAxMH0NCihwMiArIHAzKSAvIChwNCArIHA1KSAvIChwNiArIHA3KSAvIChwOCArIHA5KSArDQogICBwbG90X2Fubm90YXRpb24odGFnX2xldmVscyA9ICdhJykNCmBgYA0KDQpgYGB7ciwgZmlnLmhlaWdodD0xMiwgd2lkdGggPSAxMCwgaW5jbHVkZT1GQUxTRX0NCihncDEgKyBncDIpIC8gKGdwMyArIGdwNCkgLyAoZ3A1ICsgZ3A2KSAvIChncDcgKyBncDgpICsNCiAgIHBsb3RfYW5ub3RhdGlvbih0YWdfbGV2ZWxzID0gJ2EnKQ0KYGBgDQoNCioqRmlndXJlIDEqKi4gUG9zdGVyaW9yIG1lYW4gZXN0aW1hdGVzIGFuZCBkaWZmZXJlbmNlIGNvbnRyYXN0cyBmb3Igb2JzZXJ2ZXIgZXN0aW1hdGVkIGdyb3VwIGZvcmFnaW5nIHBlcmNlbnRhZ2UgYW5kIGluZGl2aWR1YWwgZmVlZGluZyByYXRlcy4gVGhlIGNvbG91cmVkIGFyZWEgaXMgdGhlIHBvc3RlcmlvciBkaXN0cmlidXRpb24gYW5kIHRoZSB3aGl0ZSBwb2ludCBpcyB0aGUgbWVhbiBlc3RpbWF0ZSB3aXRoIGFzc29jaWF0ZWQgNjclIGFuZCA5NSUgY3JlZGlibGUgaW50ZXJ2YWxzLiBUaGUgZGlzdHJpYnV0aW9ucyBzaG93biB3aXRoIGRhc2hlZCBsaW5lcyBhcmUgdGhlIHBvc3RlcmlvciBmb3IgYmFzZWxpbmUgcGVjayByYXRlLCBlc3RpbWF0ZWQgZnJvbSBhIHJhbmRvbSBzYW1wbGUgb2YgcGlnZW9ucyBhcHBlYXJpbmcgaW4gdGhlIHZpZGVvLg0KDQoNCiMgU2Vzc2lvbiBpbmZvDQoNCmBgYHtyfQ0Kc2Vzc2lvbkluZm8oKSAlPiUgcGFuZGVyDQpgYGANCg0K